失踪人口回归……链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1969
题意:动态断边,动态查询割边数目。
我很不明白这道题为什么可以用裸的“树剖”(明明是个仙人图啊喂)过……数据太小了?
反正这个题我没这么做……我就是按照一个比较常规的做法:在最终的图中找边双联通分量,找到之后缩点,初始化每条边权值都为$0$。缩完点倒序处理,每加一条边修改通路上所有点权值为$0$,查询时直接查询通路上几条割边。虽然说这里用了树剖但这是真的树剖啊……
做这题充分暴露蒟蒻本性……大于号打成小于号调了一个多小时……
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=30005,maxm=100005; 4 struct node 5 { 6 int from,to,next; 7 }edge[maxm<<1]; 8 int head[maxn],tot,ans[maxm],n,m; 9 void addedge(int u,int v) 10 { 11 edge[++tot]=(node){u,v,head[u]};head[u]=tot; 12 } 13 struct ques 14 { 15 int u,v,tim,val; 16 }Q[maxm<<1]; 17 inline bool cmp(const ques &a,const ques &b) 18 { 19 if(a.u!=b.u)return a.u<b.u; 20 return a.v<b.v; 21 } 22 inline bool comp(const ques &a,const ques &b) 23 { 24 return a.tim<b.tim; 25 } 26 int dfn[maxn],low[maxn],cnt,belong[maxn],scnt; 27 stack<int>s; 28 void dfs(int root,int fa) 29 { 30 dfn[root]=low[root]=++cnt;s.push(root); 31 for(int i=head[root];i;i=edge[i].next) 32 { 33 int v=edge[i].to; 34 if(!dfn[v])dfs(v,root),low[root]=min(low[root],low[v]); 35 else if(v!=fa)low[root]=min(low[root],dfn[v]); 36 } 37 if(low[root]>dfn[fa]) 38 { 39 scnt++;int k; 40 do 41 { 42 k=s.top();s.pop(); 43 belong[k]=scnt; 44 }while(k!=root); 45 } 46 } 47 int size[maxn],son[maxn],dep[maxn],pa[maxn]; 48 void dfs1(int root,int fa,int deep) 49 { 50 dep[root]=deep;size[root]=1;pa[root]=fa; 51 for(int i=head[root];i;i=edge[i].next) 52 { 53 int v=edge[i].to; 54 if(v!=fa) 55 { 56 dfs1(v,root,deep+1);size[root]+=size[v]; 57 if(size[v]>size[son[root]])son[root]=v; 58 } 59 } 60 } 61 int pos[maxn],clo,top[maxn],num; 62 void dfs2(int root,int tp) 63 { 64 pos[root]=++clo;top[root]=tp; 65 if(!son[root])return; 66 dfs2(son[root],tp); 67 for(int i=head[root];i;i=edge[i].next) 68 { 69 int v=edge[i].to; 70 if(v!=pa[root]&&v!=son[root])dfs2(v,v); 71 } 72 } 73 int sm[maxn<<2]; 74 #define mid ((l+r)>>1) 75 #define lc root<<1 76 #define rc root<<1|1 77 #define lson lc,l,mid 78 #define rson rc,mid+1,r 79 void Pushup(int root) 80 { 81 sm[root]=sm[lc]+sm[rc]; 82 } 83 void Build(int root,int l,int r) 84 { 85 if(l==r){sm[root]=(l!=1);return ;} 86 Build(lson);Build(rson);Pushup(root); 87 } 88 void Modify(int root,int l,int r,int L,int R) 89 { 90 if(L>R)return ; 91 if((L<=l&&r<=R)||!sm[root]){sm[root]=0;return;} 92 if(L<=mid)Modify(lson,L,R);if(R>mid)Modify(rson,L,R); 93 Pushup(root); 94 } 95 int Query(int root,int l,int r,int L,int R) 96 { 97 if(L>R||!sm[root])return 0; 98 if(L<=l&&r<=R)return sm[root]; 99 int res=0; 100 if(L<=mid)res+=Query(lson,L,R);if(R>mid)res+=Query(rson,L,R); 101 return res; 102 } 103 int Query(int x,int y) 104 { 105 int fx=top[x],fy=top[y],res=0; 106 while(fx^fy) 107 { 108 if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y); 109 res+=Query(1,1,clo,pos[fx],pos[x]); 110 x=pa[fx];fx=top[x]; 111 } 112 if(x==y)return res; 113 if(dep[x]>dep[y])swap(x,y); 114 res+=Query(1,1,clo,pos[x]+1,pos[y]); 115 return res; 116 } 117 void Modify(int x,int y) 118 { 119 int fx=top[x],fy=top[y]; 120 while(fx^fy) 121 { 122 if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y); 123 Modify(1,1,clo,pos[fx],pos[x]); 124 x=pa[fx];fx=top[x]; 125 } 126 if(dep[x]>dep[y])swap(x,y); 127 Modify(1,1,clo,pos[x]+1,pos[y]); 128 } 129 int haha() 130 { 131 // freopen("lane.in","r",stdin); 132 // freopen("lane.out","w",stdout); 133 scanf("%d%d",&n,&m); 134 for(int i=1;i<=m;i++) 135 { 136 scanf("%d%d",&Q[i].u,&Q[i].v); 137 if(Q[i].u>Q[i].v)swap(Q[i].u,Q[i].v); 138 } 139 sort(Q+1,Q+m+1,cmp);int t=(int)1e6; 140 int x,y,opt; 141 while(scanf("%d",&opt)!=EOF) 142 { 143 if(!(~opt))break; 144 scanf("%d%d",&x,&y);if(x>y)swap(x,y); 145 if(!opt) 146 { 147 int a=upper_bound(Q+1,Q+m+1,(ques){x,y,0,0},cmp)-Q-1; 148 Q[a].tim=t; 149 } 150 else num++,Q[m+num]=(ques){x,y,t,1}; 151 t--; 152 } 153 sort(Q+1,Q+num+m+1,comp); 154 for(int i=1;i<=num+m&&!Q[i].tim;i++) 155 addedge(Q[i].u,Q[i].v),addedge(Q[i].v,Q[i].u); 156 dfs(1,-1); 157 memset(head,0,sizeof(head)); 158 for(int i=1;i<=num+m&&!Q[i].tim;i++) 159 { 160 int u=Q[i].u,v=Q[i].v; 161 if(belong[u]!=belong[v])addedge(belong[u],belong[v]),addedge(belong[v],belong[u]); 162 } 163 dfs1(1,0,1);dfs2(1,1);Build(1,1,clo); 164 t=num; 165 for(int i=1;i<=m+num;i++) 166 { 167 if(!Q[i].tim)continue; 168 if(!Q[i].val)Modify(belong[Q[i].u],belong[Q[i].v]); 169 else 170 ans[t]=Query(belong[Q[i].u],belong[Q[i].v]),t--; 171 } 172 for(int i=1;i<=num;i++)printf("%d ",ans[i]); 173 } 174 int sb=haha(); 175 int main(){;}