您的位置:首页 > 其它

[bzoj3514] Codechef MARCH14 GERALD07加强版

2017-12-25 18:45 357 查看
裸题,Orz w_yqts

lct维护最小生成树

加边时弹出标号最小的边并记录

询问n-(l~r中小于l的数个数),可持久化线段树维护

#include <bits/stdc++.h>
using namespace std;
#define N 666666
struct lct
{
int c[2],f,to,v,rev;
}tr[3666666];
struct node
{
int c[2],v;
}Tr[3666666];
int stk
,top,Tot,rt
;
int e1
,e2
,ntr
;
int n,m,yzh,lastans;
inline int read()
{
char ch=getchar();
int x=0;
while ('0'>ch || ch>'9') ch=getchar();
while ('0'<=ch && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x;
}
inline void ins(int &x,int l,int r,int t)
{
Tr[++Tot]=Tr[x];
x=Tot;
++Tr[x].v;
if (l==r) return;
int mid=(l+r)>>1;
if (t<=mid) ins(Tr[x].c[0],l,mid,t);else ins(Tr[x].c[1],mid+1,r,t);
}
inline int query(int x,int y,int l,int r,int t)
{
if (l==r) return Tr[y].v-Tr[x].v;
int mid=(l+r)>>1;
if (t<=mid) return query(Tr[x].c[0],Tr[y].c[0],l,mid,t);
return Tr[Tr[y].c[0]].v-Tr[Tr[x].c[0]].v+query(Tr[x].c[1],Tr[y].c[1],mid+1,r,t);
}
void solve()
{
int x,y,tot=n;
x=read(),y=read();
if (yzh) x^=lastans,y^=lastans;
tot-=query(rt[x-1],rt[y],0,m,x-1);
printf("%d\n",tot);
lastans=tot;
}
inline void update(int x)
{
int l=tr[x].c[0],r=tr[x].c[1];
tr[x].to=x;
if (tr[tr[l].to].v<tr[tr[x].to].v) tr[x].to=tr[l].to;
if (tr[tr[r].to].v<tr[tr[x].to].v) tr[x].to=tr[r].to;
}
inline int isroot(int x)
{
return (!tr[x].f) || (tr[tr[x].f].c[0]!=x && tr[tr[x].f].c[1]!=x);
}
inline void rotate(int x)
{
int y=tr[x].f,z=tr[y].f,l,r;
l=(tr[y].c[1]==x);r=l^1;
if (!isroot(y)) tr[z].c[tr[z].c[1]==y]=x;
tr[tr[x].c[r]].f=y;tr[y].f=x;tr[x].f=z;
tr[y].c[l]=tr[x].c[r];tr[x].c[r]=y;
update(y);
}
inline void pushdown(int x)
{
if (!tr[x].rev) return;
int l=tr[x].c[0],r=tr[x].c[1];
swap(tr[x].c[0],tr[x].c[1]);
tr[x].rev=0;
tr[l].rev^=1;
tr[r].rev^=1;
}
inline void splay(int x)
{
int t=x;
while (!isroot(t)) stk[++top]=t,t=tr[t].f;
stk[++top]=t;
while (top) pushdown(stk[top--]);
while (!isroot(x))
{
int y=tr[x].f,z=tr[y].f;
if (!isroot(y)) if (tr[y].c[0]==x ^ tr[z].c[0]==y) rotate(x);else rotate(y);
rotate(x);
}
update(x);
}
inline void access(int x)
{
int t=0,tt=x;
while (x)
{
splay(x);
tr[x].c[1]=t;
update(x);
t=x;x=tr[x].f;
}
splay(tt);
}
inline void makeroot(int x)
{
access(x);tr[x].rev^=1;
}
inline int find(int x)
{
access(x);
while (tr[x].c[0]) x=tr[x].c[0];
return x;
}
inline void link(int x,int y)
{
if (find(x)==find(y)) return;
makeroot(x);
tr[x].f=y;
}
inline void cut(int x,int y)
{
makeroot(x);
access(y);
if (tr[y].c[0]!=x) return;
tr[y].c[0]=tr[x].f=0;
update(y);
}
int main()
{
int Q;
cin>>n>>m>>Q>>yzh;
for (int i=0;i<=n+m;++i) tr[i].to=i,tr[i].v=1000000000;
for (int i=1;i<=m;++i) e1[i]=read(),e2[i]=read();
for (int i=1;i<=m;++i)
{
if (e1[i]==e2[i]) {ntr[i]=i;continue;}
if (find(e1[i])==find(e2[i]))
{
makeroot(e1[i]);
access(e2[i]);
int t=tr[e2[i]].to;
ntr[i]=tr[t].v;
cut(e1[tr[t].v],t);
cut(e2[tr[t].v],t);
}
tr[n+i].v=i,tr[n+i].to=n+i;
link(e1[i],n+i);
link(e2[i],n+i);
}
for (int i=1;i<=m;++i) rt[i]=rt[i-1],ins(rt[i],0,m,ntr[i]);
while (Q--) solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: