• 【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
  • 相关阅读:
    Logback的配置说明
    BAT批处理修改MSDOS窗口标题、大小、字体及背景颜色
    Java修饰符public,private,protected及默认的区别
    Class loading problem regarding ear's lib directory
    MySQL开发规范
    学习如何用自己的 appender 来扩展 log4j 框架
    指令重排、内存屏障概念解析
    高性能线程间队列 DISRUPTOR 简介
    Log4j2的性能为什么这么好?
    java多线程
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6875357.html
Copyright © 2020-2023  润新知