主席树求调 (悬关)
查看原帖
主席树求调 (悬关)
749665
huta0楼主2024/4/6 18:02
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<map>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define a_all a.begin(),a.end()
using namespace std;
typedef long long ll;
int n,m,q,t,l,r,lst;
struct egde { int u,v; } e[200010];
namespace hikari {
      struct node {
            int p,v=20010,mn=20010,tag,uu,vv,st;
            int s[2];
      } tr[200010];
      #define fa(x) tr[x].p
      #define lc(x) tr[x].s[0]
      #define rc(x) tr[x].s[1]
      #define ntrt(x) lc(fa(x))==x||rc(fa(x))==x
      void pushup(int x) {
            tr[x].mn=min(tr[x].v,min(tr[lc(x)].mn,tr[rc(x)].mn));
      }
      void pushdown(int x) {
            if(tr[x].tag) {
                  swap(lc(x),rc(x));
                  tr[lc(x)].tag^=1;
                  tr[rc(x)].tag^=1;
                  tr[x].tag=0;
            }
      }
      void pushall(int x) {
            if(ntrt(x)) pushall(fa(x));
            pushdown(x);
      }
      void rotate(int x) {
            int y=fa(x),z=fa(y);
            int k= rc(y)==x;
            if(ntrt(y))
                 tr[z].s[rc(z)==y]=x;
            fa(x)=z;
            tr[y].s[k]=tr[x].s[k^1];
            fa(tr[x].s[k^1])=y;
            tr[x].s[k^1]=y;
            fa(y)=x;
            pushup(y); pushup(x);
      }
      void splay(int x) {
            pushall(x);
            while(ntrt(x)) {
                  int y=fa(x),z=fa(y);
                  if(ntrt(y))
                       rotate((rc(y)==x)^(rc(z)==y)?x:y);
                  rotate(x);
            }
      }
      void access(int x) {
            int y=0;
            while(x) {
                  splay(x);
                  rc(x)=y;
                  pushup(x);
                  y=x; x=fa(x);
            }
      }
      void mkrt(int x) {
            access(x);
            splay(x);
            tr[x].tag^=1;
      }
      int fdrt(int x) {
            access(x);
            splay(x);
            while(lc(x)) pushdown(x),x=lc(x);
            splay(x);
            return x;
      }
      void split(int x,int y) {
             mkrt(x);
             access(y);
             splay(y);
      }
      void link(int x,int y) {
            mkrt(x);
            if(fdrt(y)!=x) fa(x)=y;
      }
      void cut(int x,int y) {
            mkrt(x);
            if(fdrt(y)==x&&fa(y)==x&&!lc(y)) {
                  rc(x)=fa(y)=0;
                  pushup(x);
            }
      }
      void change(int x,int val) {
           splay(x);
           tr[x].v=val;
      }
};
using namespace hikari;
int fat[100010];
#define init rep(i,1,n) fat[i]=i
int find(int x) { return fat[x]==x?x:fat[x]=find(fat[x]); }
void merge(int x,int y) { if(find(x)!=find(y)) fat[find(x)]=find(y); }
#define cot(x,y) find(x)==find(y)
namespace ai {
     struct node { int ch[2],sum;} tr[100005*22];
     #define lc(x) tr[x].ch[0]
     #define rc(x) tr[x].ch[1]
     int rt[100005],id=0,tmp;
     inline void modify(int &y,int l,int r,int L,int R,int v) {
           tmp=++id; tr[tmp]=tr[y];tr[tmp].sum+=v; y=tmp;
           if(l==r) return;
           int mid=l+r>>1;
           if(L<=mid) modify(lc(y),l,mid,L,R,v);
           else modify(rc(y),mid+1,r,L,R,v);
     }
     inline int query(int y,int l,int r,int L,int R) {
           if(l<=L&&R<=r) return tr[y].sum;
           int mid=l+r>>1,v=0;
           if(L<=mid) v+=query(lc(y),l,mid,L,R);
           if(R>mid) v+=query(rc(y),mid+1,r,L,R);
           return v;
     }
} 
void get(int& l,int& r,int t,int lsta) {
      if(t) {
           l=(l+t*lsta)%m+1;
           r=(r+t*lsta)%m+1;
      } if(l>r) swap(l,r);
}
int tot,ctt;
map<pair<int,int>,int> mp;
int main() {
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>q>>t; tot=n;
    init;
    rep(i,1,m) {
          cin>>e[i].u>>e[i].v;
          if(e[i].u==e[i].v) continue;
          ai::rt[i]=ai::rt[i-1];
          int aa=e[i].u,bb=e[i].v;
          if(aa==bb) continue;
          ai::modify(ai::rt[i],1,m,i,i,1);
          if(cot(aa,bb)) {
                 split(aa,bb);
                 int uu=e[tr[bb].mn-n].u,vv=e[tr[bb].mn-n].v;
                 cut(uu,tr[bb].mn); cut(tr[bb].mn,vv);
                 ai::modify(ai::rt[i],1,m,tr[bb].mn-n,tr[bb].mn-n,-1);
          }
          else merge(aa,bb);
          tr[i+n].v=i+n;
          link(aa,i+n); link(i+n,bb);
    }
    rep(i,1,q) {
          cin>>l>>r;
          get(l,r,t,lst);
          cout<<(lst=n-ai::query(ai::rt[r],1,m,l,r))<<endl;
    }
    return 0;
}
2024/4/6 18:02
加载中...