【BZOJ3514】 Codechef MARCH14 GERALD07加强版

hentai。。。

原题:

N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

对于100%的数据,1≤N、M、K≤200,000。

直接复制wulala的题解

wulala

葱娘说这是一个很巧妙的题。。
有一个比较猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去
并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;
这个显然是可以用LCT来弄的对吧。
然后对于每个询问,我们的答案就是对l~r中ntr小于l的边求和,并用n减去这个值
正确性可以YY一下:
如果一条边的ntr >= l,那么显然他可以与从l ~ r中的边形成环,那么它对答案没有贡献
反之如果一条边的ntr < l那么它与从l ~ r中的边是不能形成环的,那么他对答案的贡献为-1
对于查询从l ~ r中有多少边的ntr小于l,我反正是用的函数式线段树

 

好妙啊

ntr。。。真是hentai,让我传承传承了hentai的po姐美好的意境吧

这题我写了一下午

T?WA我也认了T什么鬼啊
然后找rxz要来70M的数据。。。
突然想起来有些点是强制在线的,然后感觉就是我WA了
但是我把不强制在线的数据跑一下答案没错啊?
又从头到尾查一下,找不到毛病啊?
然后gdb,跟踪到第一个数据的时候……
一拍脑袋,发现last_ans没设初值。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 const int inf=(int)1e9;
  8 int rd(){int z=0;  char ch=getchar();
  9     while(ch<'0'||ch>'9')  ch=getchar();
 10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
 11     return z;
 12 }
 13 struct edg{int x,y;}e[210000];
 14 int n,m,o,mk;
 15 int fth[410000],chd[410000][2],v[410000],mnv[410000],rvs[410000];
 16 int stck[410000],tp=0;
 17 int ntr[210000],c[210000];
 18 int w[8100000],cwd[8100000][2],rts[210000],ndc=0;
 19 inline bool isrt(int x){  return (chd[fth[x]][0]!=x)&(chd[fth[x]][1]!=x);}
 20 inline void pshu(int x){  mnv[x]=min(v[x],min(mnv[chd[x][0]],mnv[chd[x][1]]));}
 21 inline void pshd(int x){
 22     if(!rvs[x])  return ;
 23     rvs[chd[x][0]]^=1,rvs[chd[x][1]]^=1,rvs[x]=0;
 24     swap(chd[x][0],chd[x][1]);
 25 }
 26 void rtt(int x){
 27     int y=fth[x],z=fth[fth[x]],l,r;
 28     r=(chd[y][0]==x);  l=r^1;
 29     if(!isrt(y))  chd[z][chd[z][1]==y]=x;
 30     fth[x]=z,fth[y]=x,fth[chd[x][r]]=y;
 31     chd[y][l]=chd[x][r],chd[x][r]=y;
 32     pshu(y),pshu(x);
 33 }
 34 void sply(int x){
 35     stck[tp=1]=x;
 36     for(int i=x;!isrt(i);i=fth[i])  stck[++tp]=fth[i];
 37     while(tp)  pshd(stck[tp--]);
 38     while(!isrt(x)){
 39         if(!isrt(fth[x]))  rtt((chd[fth[x]][0]==x)^(chd[fth[fth[x]]][0]==fth[x])?x:fth[x]);
 40         rtt(x);
 41     }
 42 }
 43 inline void accs(int x){  for(int i=0;x;sply(x),chd[x][1]=i,pshu(x),x=fth[i=x]);}
 44 inline void qdrt(int x){  accs(x),sply(x),rvs[x]^=1;}
 45 inline void ct(int x,int y){  qdrt(x),accs(y),sply(y),chd[y][0]=fth[x]=0;}
 46 inline void lk(int x,int y){  qdrt(x),fth[x]=y,sply(x);}
 47 inline int gtrt(int x){  while(fth[x])  x=fth[x];  return x;}
 48 inline int sch(int x,int y){  qdrt(x),accs(y),sply(y);  return mnv[y];}
 49 void ist(int x){
 50     if(e[x].x==e[x].y){  ntr[x]=x;  return ;}
 51     if(gtrt(e[x].x)==gtrt(e[x].y)){
 52         ntr[x]=sch(e[x].x,e[x].y);
 53         ct(n+ntr[x],e[ntr[x]].x),ct(n+ntr[x],e[ntr[x]].y);
 54         mnv[n+ntr[x]]=inf;
 55     }
 56     mnv[n+x]=v[n+x]=x;
 57     lk(n+x,e[x].x),lk(n+x,e[x].y);
 58 }
 59 /*int bnrsch(int x){
 60     int l=1,r=m,md;
 61     while(l+1<r)  md=(l+r)>>1,(c[md]>=x ? l : r)=md;
 62     return c[md]==l ? l : r;
 63 }*/
 64 int gtsgmttr(int l,int r){
 65     int x=++ndc,md=(l+r)>>1;
 66     if(l!=r)  cwd[x][0]=gtsgmttr(l,md),cwd[x][1]=gtsgmttr(md+1,r);
 67     return x;
 68 }
 69 int mdf(int x,int l,int r,int y,int z){
 70     w[++ndc]=w[x],cwd[ndc][0]=cwd[x][0],cwd[ndc][1]=cwd[x][1],x=ndc;
 71     if(l==r){  w[x]+=z;  return x;}
 72     int md=(l+r)>>1;
 73     if(y<=md)  cwd[x][0]=mdf(cwd[x][0],l,md,y,z);
 74     else  cwd[x][1]=mdf(cwd[x][1],md+1,r,y,z);
 75     w[x]=w[cwd[x][0]]+w[cwd[x][1]];
 76     return x;
 77 }
 78 int qur(int x,int l,int r,int ql,int qr){
 79     if(l==ql && r==qr)  return w[x];
 80     int md=(l+r)>>1;
 81     if(ql<=md && qr>md)  return qur(cwd[x][0],l,md,ql,md)+qur(cwd[x][1],md+1,r,md+1,qr);
 82     else if(qr<=md)  return qur(cwd[x][0],l,md,ql,qr);
 83     else  return qur(cwd[x][1],md+1,r,ql,qr);
 84 }
 85 int main(){//freopen("ddd.in","r",stdin);
 86     //freopen("ddd.out","w",stdout);
 87     int l,r,lst;
 88     cin>>n>>m>>o>>mk;
 89     fill(mnv,mnv+m+n+1,inf),fill(v,v+m+n+1,inf);
 90     for(int i=1;i<=m;++i)  e[i].x=rd(),e[i].y=rd(),ist(i);
 91     /*for(int i=1;i<=m;++i)  c[i]=ntr[i];
 92     sort(c+1,c+m+1);
 93     for(int i=1;i<=m;++i)  ntr[i]=bnrsch(ntr[i]);*/
 94     rts[0]=gtsgmttr(0,m);
 95     for(int i=1;i<=m;++i)  rts[i]=mdf(rts[i-1],0,m,ntr[i],1);
 96     lst=0;
 97     for(int i=1;i<=o;++i){
 98         l=rd()^(mk*lst),r=rd()^(mk*lst);
 99         printf("%d
",lst=n-qur(rts[r],0,m,0,l-1)+qur(rts[l-1],0,m,0,l-1));
100     }
101     return 0;
102 }
View Code
原文地址:https://www.cnblogs.com/JSL2018/p/6875357.html