luogu2542 航线规划 (树链剖分)

不会lct,所以只能树剖乱搞

一般这种删边的题都是离线倒着做,变成加边

他要求的结果其实就是缩点以后两点间的距离。

然后先根据最后剩下的边随便做出一个生成树,然后假装把剩下的边当成加边操作以后处理

这样的话,就可以做树剖来维护现在的两点间距离。

然后考虑加边,其实就是加了一条边然后某一处成环了,缩成了一个点。

这样的话,就可以把这条边两个端点间的距离都改成0,假装缩了点。

最后再倒着输出答案就行了。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<queue>
  6 #include<map>
  7 #include<cmath>
  8 #define inf 0x3f3f3f3f
  9 #define LL long long int
 10 using namespace std;
 11 const int maxn=30030,maxm=100010,maxq=40040;
 12 
 13 inline LL rd(){
 14     LL x=0;char c=getchar();int neg=1;
 15     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
 16     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 17     return x*neg;
 18 }
 19 
 20 struct Edge{
 21     int a,b,ne;bool used,flag;
 22 }eg[maxm*2];
 23 int N,M;
 24 int egh[maxn],ect;
 25 int que[maxq][3],ans[maxq],qct;
 26 int fa[maxn],dep[maxn],wson[maxn],siz[maxn],top[maxn],root[maxn],len[maxn];
 27 int ch[maxn*4][2],val[maxn*4],pct;
 28 bool laz[maxn*4];
 29 map<int,int> mp;
 30 
 31 inline void adeg(int a,int b){
 32     eg[ect].a=a;eg[ect].b=b;eg[ect].ne=egh[a];eg[ect].used=1;egh[a]=ect++;
 33 }
 34 
 35 inline void pushdown(int p){
 36     if(!laz[p]) return;
 37     val[ch[p][0]]=val[ch[p][1]]=laz[p]=0;
 38     laz[ch[p][0]]=laz[ch[p][1]]=1;
 39 }
 40 inline void update(int p){pushdown(p);val[p]=val[ch[p][0]]+val[ch[p][1]];}
 41 
 42 void build(int &p,int l,int r){
 43     p=++pct;
 44     if(l==r) val[p]=1;
 45     else{
 46         int m=l+r>>1;
 47         build(ch[p][0],l,m);build(ch[p][1],m+1,r);
 48         update(p);
 49     }
 50 }
 51 
 52 int query(int p,int l,int r,int x,int y){
 53     if(x<=l&&r<=y) return val[p];
 54     else{
 55         pushdown(p);int m=l+r>>1,re=0;
 56         if(x<=m) re+=query(ch[p][0],l,m,x,y);
 57         if(y>=m+1) re+=query(ch[p][1],m+1,r,x,y);
 58         return re;
 59     }
 60 }
 61 
 62 void change(int p,int l,int r,int x,int y){
 63     if(x<=l&&r<=y){
 64         val[p]=0;laz[p]=1;pushdown(p);
 65     }else if(val[p]!=0){
 66         pushdown(p);int m=l+r>>1;
 67         if(x<=m) change(ch[p][0],l,m,x,y);
 68         if(y>=m+1) change(ch[p][1],m+1,r,x,y);
 69         update(p);
 70     }
 71 }
 72 
 73 void dfs1(int x){
 74     siz[x]=1;int ma=0;
 75     for(int i=egh[x];i!=-1;i=eg[i].ne){
 76         int b=eg[i].b;
 77         if(!eg[i].used||dep[b]) continue;
 78         eg[i].flag=eg[i^1].flag=1;
 79         fa[b]=x;dep[b]=dep[x]+1;
 80         dfs1(b);siz[x]+=siz[b];
 81         if(siz[b]>ma) ma=siz[b],wson[x]=b;
 82     }
 83 }
 84 
 85 void dfs2(int x){
 86     if(x!=wson[fa[x]]){int d=0;
 87         for(int i=x;i;i=wson[i]) top[i]=x,d++;
 88         build(root[x],1,d);len[x]=d;
 89     }for(int i=egh[x];i!=-1;i=eg[i].ne){
 90         int b=eg[i].b;
 91         if(eg[i].flag&&fa[x]!=b) dfs2(b);
 92     }
 93 }
 94 
 95 void solveC(int x,int y){
 96     while(top[x]!=top[y]){
 97         if(dep[top[x]]<dep[top[y]]) swap(x,y);
 98         change(root[top[x]],1,len[top[x]],1,dep[x]-dep[top[x]]+1);x=fa[top[x]];
 99     }if(x==y) return;
100     if(dep[x]>dep[y]) swap(x,y);
101     change(root[top[x]],1,len[top[x]],dep[x]-dep[top[x]]+2,dep[y]-dep[top[y]]+1);
102 }
103 int solveQ(int x,int y){
104     int re=0;
105     while(top[x]!=top[y]){
106         
107         if(dep[top[x]]<dep[top[y]]) swap(x,y);
108         re+=query(root[top[x]],1,len[top[x]],1,dep[x]-dep[top[x]]+1);x=fa[top[x]];
109     }if(x==y) return re;
110     if(dep[x]>dep[y]) swap(x,y);
111     return re+query(root[top[x]],1,len[top[x]],dep[x]-dep[top[x]]+2,dep[y]-dep[top[y]]+1);
112 }
113 
114 int main(){
115     int i,j,k;
116     N=rd();M=rd();memset(egh,-1,sizeof(egh));
117     for(i=1;i<=M;i++){
118         int a=rd(),b=rd();
119         mp[a*N+b]=ect;adeg(a,b);
120         mp[b*N+a]=ect;adeg(b,a);
121     }while(++qct){
122         int a=rd();if(a==-1) break;
123         int b=rd(),c=rd();
124         que[qct][0]=a;que[qct][1]=b;que[qct][2]=c;
125         if(!a){
126             int x=mp[b*N+c];
127             eg[x].used=eg[x^1].used=0;
128         }
129     }dep[1]=1;dfs1(1);dfs2(1);
130     for(i=0;i<ect;i++){
131         if((!eg[i].flag)&&eg[i].used) solveC(eg[i].a,eg[i].b);
132     }int act=0;
133     for(i=qct-1;i;i--){
134         if(!que[i][0]) solveC(que[i][1],que[i][2]);
135         else ans[++act]=solveQ(que[i][1],que[i][2]);
136     }for(i=act;i;i--) printf("%d
",ans[i]);
137     return 0;
138 }
原文地址:https://www.cnblogs.com/Ressed/p/9486223.html