CF1148H神圣潜水员
一、题目
单击此处查看问题。
二、解法
输入特性需求的方法是移动正确的端点,然后维护一些东西。
首先考虑如何维护\([l,r]\)的\(mex\),应该尽量放在一个简单的数据结构上,因为更新它应该对应更新答案的数据结构。首先,观察到\(mex\)大约\(l\)没有下降。考虑添加某个数字\(a\),只有\(mex=a\)的段\([p,q]\)会受到影响。
考虑到该段的\(mex\)将如何变化,我们发现最小权重\(va\)满足\(p[v]\ leq \)(其中\(p[v]\)表示最后出现的位置),然后\ ((p [v],q])。然后我们将\(a\)设置为\(v\)并将\(q\)设置为\(p[v]\)以继续循环。因为段的总数是\(O(n)\),每次修改会增加一个段,所以平均分布的修改数是\(O(n)\)。
在具体实现中,线段树二进制维护\(p\)数组可以用来支持查询。
高维统计问题可以考虑贡献法、差分法,考虑一个修改\((i,l,r,x)\),即在时间\(i\),永久修改把区间\([l,r]\)的权值变成\(x\)(这里需要差,所以我们可以在删除的时候加一个负的修改),然后如果在时间,((矩表示右端点),那么这个修改的贡献就是\(j-I ^ 1 \),这样我们就可以通过保持线段树中的系数\(1\)和\(i\)进行查询。
对于每一种权重,我们都需要打开一个线段树,这样我们就可以动态打开它,共享一个内存池。因为可以查询以前的时间,所以需要使用永久标记的主席树,时间复杂度为\(O(n\log n)\)。
三、总结
对于高层统计问题(比如统计一个区间的子区间),我们可以考虑保持历史和;您也可以考虑计算每次修改的贡献。此时,可以通过使用差值将其更改为永久修改,以方便计算。
有必要对如何维护某个东西有一个大概的概念,比如主体(MEX)的维护,因为不可能用一些复杂的结构对线段树进行更改,只能进行剧烈的更改。所以你需要弄清楚维修应该在立刻的还是延时的.
#包含cstdio
#包含矢量
#包含iostream
#包含算法
#包含集
使用命名空间标准;
const int M=200005
const int N=60 * M;
#定义整数长
#定义pii pairint,int
#定义mp制作对
int read()
{
int x=0,f=1;char c;
while((c=getchar())' 0 ' | | c ' 9 '){ if(c=='-')f=-1;}
while(c=' 0 ' c=' 9 '){ x=(x3)(x1)(c^48);c=getchar();}
返回x * f;
}
int n,m,cnt,ls[N],rs[N],s1[N],s2[N],t1[N],T2[N];
结构节点
{
int w,l,r;
布尔运算符(常量节点b)常量
{
return w==b . wrb . r : WB . w;
}
};set node s;
命名空间T1
{
int mi[4 * M];
void ins(int i,int l,int r,int id,int x)
{
if(l==r){ mi[I]=x;返回;}
int mid=(l r)1;
if(mid=id) ins(i1,l,mid,id,x);
else ins(i1|1,mid 1,r,id,x);
mi[i]=min(mi[i1],mi[i1 | 1]);
}
pii ask(int i,int l,int r,int id,int x)
{
if(mi[i]x)返回mp(0,0);
if(l==r)返回mp(l,mi[I]);
int mid=(l r)1;
if(mid=id)
{
pii t=ask(i1,l,mid,id,x);
回来!t.firstask(i1|1,mid 1,r,id,x):t;
}
返回询问(i1|1,mid 1,r,id,x);
}
}
结构化T2
{
矢量位置,rt;int w1,w2;
void add(int x,int y,int l,int r,int L,int R)
{
if(lR || Lr)返回;
x=cnt
ls[x]=ls[y];RS[x]=RS[y];T2[x]=T2[y];
S1[x]=S1[y];S2[x]=S2[y];t1[x]=t1[y];
if(L=l r=R)
{
S1[x]=w1 *(r-l 1);t1[x]=w1;
S2[x]=w2 *(r-l 1);T2[x]=w2;
返回;
}
int mid=(l r)1;
相加(ls[x],ls[y],L,mid,L,R);
相加(rs[x],rs[y],mid 1,R,L,R);
S1[x]=S1[ls[x]]S1[RS[x]](r-l 1)* t1[x];
S2[x]=S2[ls[x]]S2[RS[x]](r-l 1)* T2[x];
}
pii ask(int x,int l,int r,int L,int R)
{
if(Lr || lR ||!x)返回mp(0,0);
if(L=l r=R)返回mp(s1[x],S2[x]);
int mid=(l,r)1,len=min(r,R)-max(L,L)1;
pii v1=ask(ls[x],L,mid,L,R)、
v2=ask(rs[x],mid 1,R,L,R);
返回mp(v1.first v2.first t1[x]*len,
v1 . second v2 . second T2[x]* len);
}
void ins(int i,int l,int r,int a,int b)
{
rt . push _ back(0);pos . push _ back(I);
w1=a;w2=b;int p=rt . size()-1;
add(rt[p],prt[p-1]:0,1,n,l,r);
}
int qry(国际,国际r)
{
int q=上界(pos.begin(),pos.end(),r)-
pos。begin()-1;if(q0)返回0;
pii ans=ask(rt[q],1,n,l,r);
返回ans。第一*(R1)-ans。第二;
}
} h[M];
int zxy(int a,int l,int r,int k,int i)
{
int u=a 0:1t 1:3360 ins(1,0,n,a,I);
setnode:iterator it=s。下界(节点{a,0,0 });
如果(它!=s.end() it-w==a)
{
int p=it-l,q=it-r;s.erase(它);
//删除永久标签
h[a].ins(i,p,q,-1,-I);
而(p=q)//为新墨西哥工作
{
pii nx=T1:ask(1,0,n,a 1,q);
if(nx.secondp)//all mex=a
{
s.insert(节点{nx.first,p,q });
h[nx.first].ins(i,p,q,1,I);
a=nx.first打破;
}
if(nx.secondq)//(nx,q] mex=a
{
s.insert(节点{nx.first,nx.second 1,q });
h[nx.first].ins(i,nx.second 1,q,1,I);
}
a=nx.firstq=nx.second
}
//现在我们合并同一个段
它=s。下界(节点{a,0,0 });
如果(它!=s.end() it-w==a)
{
节点tmp=* it它;
如果(它!=s.end() it-w==a)
{
s。擦除(s . find(tmp));
tmp。r=it-r;
s.erase(它);
s。插入(tmp);
}
}
}
它=s。下界(节点{u,0,0 });
如果(它!=s.end() it-w==u)
{
节点tmp=* ittmp.r
s.erase(它);s . insert(tmp);
}
else s.insert(节点{u,I,I });
h[u].ins(i,I,I,1,I);
返回h[k].qry(l,r);
}
签名main()
{
n=read();int ans=0;
for(int I=1;I=n;(一)
{
int a=read(),l=read(),r=read(),k=read();
a=(a ans)%(n ^ 1);k=(k ans)%(n ^ 1);
l=(l ans)% I ^ 1;r=(r ans)% I ^ 1;
中频(左后)交换(l,r);
printf('%lld\n ',ans=zxy(a,l,r,k,I));
}
}
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/52954.html