bzoj1969 LANE航线规划 边双联通分量

失踪人口回归……链接: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\n",ans[i]);
173 }
174 int sb=haha();
175 int main(){;}
bzoj1969

 

posted @ 2017-10-20 20:49  ccc000111  阅读(280)  评论(0编辑  收藏  举报