您的位置:首页 > 其它

BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]

2018-01-24 14:40 423 查看

ZHX的题目。

类似于HH的项链我们考虑最后加入哪一条边以后合并了两个联通块,所以我们边权从大到小排然后依次加入。找出最晚加入的,记成last。

然后做主席树就好啦!

注意拆边为点。

By:大奕哥

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int c
[2],mx
,fa
,w
,pos
,rev
,s
;
int last
,rt
,cnt,n,m,k,type,ans,l,r;
struct node{
int s,l,r;
}t[N<<2];
struct edge{
int x,y;
}a
;
bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void update(int x)
{
mx[x]=w[x];pos[x]=x;
if(mx[x]<mx[c[x][0]])mx[x]=mx[c[x][0]],pos[x]=pos[c[x][0]];
if(mx[x]<mx[c[x][1]])mx[x]=mx[c[x][1]],pos[x]=pos[c[x][1]];
return;
}
void pushup(int x)
{
if(rev[x])
{
rev[x]^=1;rev[c[x][0]]^=1;rev[c[x][1]]^=1;
swap(c[x][0],c[x][1]);
}
return;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
l=c[y][1]==x;r=l^1;
if(!isroot(y))c[z][c[z][1]==y]=x;
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
update(y);update(x);
return;
}
void splay(int x)
{
int top=0,i;
for(i=x;!isroot(i);i=fa[i])s[++top]=i;s[++top]=i;
for(i=top;i;--i)pushup(s[i]);
while(!isroot(x))
{
//        cout<<x<<endl;
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if(c[y][0]==x^c[z][0]==y)rotate(x);
else rotate(y);
}
rotate(x);
}
return;
}
void access(int x)
{
int y=0;
while(x)
{
splay(x);
c[x][1]=y;
y=x;x=fa[x];
}
return;
}
void mroot(int x)
{
access(x);splay(x);rev[x]^=1;
}
void cut(int x,int y)
{
mroot(x);access(y);splay(y);c[y][0]=fa[x]=0;
}
void link(int x,int y)
{
mroot(x);fa[x]=y;splay(x);
}
int query(int x,int y)
{
mroot(x);access(y);splay(y);return pos[c[y][0]];
}
int f
;
inline int get(int x)
{
return x==f[x]?x:f[x]=get(f[x]);
}
void solve()
{
for(int i=1;i<=n+m;++i)f[i]=i;
for(int i=1;i<=m;++i)
{
int fx=get(a[i].x);int fy=get(a[i].y);
if(a[i].x==a[i].y){
last[i]=i;continue;
}
if(fx==fy)
{
int tmp=query(a[i].x,a[i].y);
last[i]=tmp-n;
cut(tmp,a[tmp-n].x);cut(tmp,a[tmp-n].y);
}
link(a[i].x,i+n);link(a[i].y,i+n);f[fx]=fy;
}
return;
}
void change(int &x,int l,int r,int pos)
{
t[++cnt]=t[x];x=cnt;
if(l==r){
t[x].s++;return;
}
int mid=l+r>>1;
if(pos>mid)change(t[x].r,mid+1,r,pos);
else change(t[x].l,l,mid,pos);
t[x].s=t[t[x].l].s+t[t[x].r].s;
return;
}
int querysum(int x,int y,int l,int r,int L,int R)
{
if(l==L&&r==R)return t[y].s-t[x].s;
int mid=l+r>>1;
if(mid>=R)return querysum(t[x].l,t[y].l,l,mid,L,R);
else if(mid<L)return querysum(t[x].r,t[y].r,mid+1,r,L,R);
else return querysum(t[x].l,t[y].l,l,mid,L,mid)+querysum(t[x].r,t[y].r,mid+1,r,mid+1,R);
}
void work()
{
for(int i=1;i<=m;++i)rt[i]=rt[i-1],change(rt[i],0,m,last[i]);
for(int i=1;i<=k;++i)
{
scanf("%d%d",&l,&r);if(type)l^=ans,r^=ans;
ans=querysum(rt[l-1],rt[r],0,m,0,l-1);ans=n-ans;
printf("%d\n",ans);
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&type);
for(int i=1;i<=m;++i)
{
scanf("%d%d",&a[i].x,&a[i].y);
w[i+n]=m+n-i+1;mx[i+n]=m+n-i+1;pos[i+n]=i+n;
}
solve();
work();
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: