题解:

每一次加入一条边,记录一下弹出了那一条边

然后用lct维护即可

计算出来后,再用主席树做l-r的值

代码:

#include<bits/stdc++.h>
typedef long long ll;
const int N=400005;
using namespace std;
int type,n,m,Q,lastans,top,l,r,tot,sz,s[N],st[N],root[N];
int c[N][2],fa[N],val[N],mn[N],sum[N*10],ls[N*10],rs[N*10],rev[N];
struct edge{int u,v;}e[N];
int isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void update(int x)
{
    int l=c[x][0],r=c[x][1];
    mn[x]=x;
    if (val[mn[l]]<val[mn[x]])mn[x]=mn[l];
    if (val[mn[r]]<val[mn[x]])mn[x]=mn[r];    
}
void pushdown(int x)
{
    int l=c[x][0],r=c[x][1];
    if (rev[x])
     {
        rev[x]^=1;rev[l]^=1;rev[r]^=1;
        swap(c[x][0],c[x][1]);
     }
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],l,r;
    if (c[y][0]==x)l=0;else l=1;r=l^1;
    if (!isroot(y))
      {
        if(c[z][0]==y)c[z][0]=x;
        else c[z][1]=x;
     }
    fa[y]=x;fa[x]=z;fa[c[x][r]]=y;
    c[y][l]=c[x][r];c[x][r]=y;
    update(y);update(x);
}
void down(int x){if (!isroot(x))down(fa[x]);pushdown(x);}
void splay(int x)
{
    down(x);
    for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
     if (!isroot(y))rotate((c[y][0]==x)==(c[fa[y]][0]==y)?y:x);
}
void access(int x){for (int t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,update(x);}
void makeroot(int x){access(x);splay(x);rev[x]^=1;}
void link(int x,int y){makeroot(x);fa[x]=y;}
void cut(int x,int y){makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;}
int find(int x){access(x);splay(x);while (c[x][0])x=c[x][0];return x;}
int query(int x,int y){makeroot(x);access(y);splay(y);return mn[y];}
void insert(int l,int r,int x,int &y,int val)
{
    y=++sz;
    sum[y]=sum[x]+1;
    if(l==r)return;
    ls[y]=ls[x];rs[y]=rs[x];
    int mid=(l+r)/2;
    if (val<=mid)insert(l,mid,ls[x],ls[y],val);
    else insert(mid+1,r,rs[x],rs[y],val);
}
int query(int l,int r,int x,int y,int val)
{
    if (r==val)return sum[y]-sum[x];
    int mid=(l+r)/2;
    if (val<=mid)return query(l,mid,ls[x],ls[y],val);
    return sum[ls[y]]-sum[ls[x]]+query(mid+1,r,rs[x],rs[y],val);
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&Q,&type);
    val[0]=1e9;
    for (int i=1;i<=n;i++)mn[i]=i,val[i]=1e9;
    for (int i=1;i<=m;i++)scanf("%d%d",&e[i].u,&e[i].v);
    tot=n;
    for (int i=1;i<=m;i++)
     {
        int u=e[i].u,v=e[i].v;
        if (u==v){st[i]=i;continue;}
        if (find(u)==find(v))
         {
            int t=query(u,v),x=val[t];
            st[i]=x;
            cut(e[x].u,t);cut(e[x].v,t);
         }
        tot++;
        mn[tot]=tot;val[tot]=i;
        link(u,tot);link(v,tot);
     }
    for (int i=1;i<=m;i++)insert(0,m,root[i-1],root[i],st[i]);
    while (Q--)
     {
         scanf("%d%d",&l,&r); 
        if (type)l^=lastans,r^=lastans;
        lastans=n-query(0,m,root[l-1],root[r],l-1);
        printf("%d\n",lastans);
     }
    return 0;
}

 

posted on 2017-12-12 20:15  宣毅鸣  阅读(152)  评论(1编辑  收藏  举报