zoukankan      html  css  js  c++  java
  • BZOJ 1969 树链剖分+Tarjan缩点

    发现自己Tarjan的板子有错误.发现可以用Map直接删去边,Get.

    听说std是双连通、LCA、并查集、离线思想、用BIT维护dfs序和并查集维护LCA的动态缩点的好题

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <map>
      7 #include <set>
      8 #include <stack>
      9 #define mp make_pair
     10 #define pa pair<int,int>
     11 #define pb push_back
     12 #define fi first
     13 #define se second
     14 using namespace std;
     15 inline void Get_Int(int &x)
     16 {
     17     x=0;  char ch=getchar(); int f=1;
     18     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     19     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
     20 }
     21 inline void Put_Int(int x)
     22 {
     23     char ch[20]; int top=0;
     24     if (x==0) ch[++top]='0';
     25     while (x) ch[++top]=x%10+'0',x/=10;
     26     while (top) putchar(ch[top--]); putchar('
    ');
     27 }
     28 //===================================================
     29 const int Maxm=200100;
     30 const int Maxn=30100;
     31 const int Maxop=40100;
     32 struct EDGE{int to,next;}edge[Maxm];
     33 struct OP{int type,u,v;}Op[Maxop];
     34 int head[Maxn],siz[Maxn],father[Maxn],top[Maxn],dep[Maxn],num[Maxn],sum[Maxn<<2],clr[Maxn<<2];
     35 int Belong[Maxn],Low[Maxn],Dfn[Maxn],Ans[Maxn];
     36 int Stack[Maxn];
     37 int stamp,Stamp,cnt,scc,apex,Q,n,m,u,v;
     38 bool vis[Maxn];
     39 map<pa,bool> Edge;
     40 vector<pa> V;
     41 set <pa> S;
     42 inline void Add(int u,int v) 
     43 {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
     44 inline int Max(int x,int y) {return x>y?x:y;}
     45 inline int Min(int x,int y) {return x>y?y:x;}
     46 inline void Build_G()
     47 {
     48     map<pa,bool>::iterator it;
     49     for (it=Edge.begin();it!=Edge.end();it++)
     50         if (it->se) 
     51             Add(it->fi.fi,it->fi.se);
     52 }
     53 inline void Clear_G()
     54 {    
     55     map<pa,bool>::iterator it;
     56     for (it=Edge.begin();it!=Edge.end();it++)
     57         if (it->se) it->se=false;
     58 }
     59 //=================================================
     60 
     61 void Dfs1(int u)
     62 {
     63     vis[u]=true; siz[u]=1;
     64     for (int i=head[u];i!=-1;i=edge[i].next)
     65         if (!vis[edge[i].to]) 
     66         {
     67             father[edge[i].to]=u;
     68             dep[edge[i].to]=dep[u]+1;
     69             Dfs1(edge[i].to);
     70             siz[u]+=siz[edge[i].to];
     71         }
     72 }
     73 void Dfs2(int u,int chain)
     74 {
     75     num[u]=++stamp; top[u]=chain; vis[u]=true; int k=0;
     76     for (int i=head[u];i!=-1;i=edge[i].next)
     77         if (!vis[edge[i].to] && (siz[edge[i].to]>siz[k] || k==0)) k=edge[i].to;
     78     if (k==0) return;
     79     Dfs2(k,chain);
     80     for (int i=head[u];i!=-1;i=edge[i].next)
     81         if (!vis[edge[i].to] && edge[i].to!=k) Dfs2(edge[i].to,edge[i].to);
     82 }
     83 
     84 inline int Lca(int u,int v) 
     85 {
     86     while (true)
     87     {
     88         if (top[u]==top[v]) return dep[u]>dep[v]?v:u;
     89         if (dep[top[u]]>dep[top[v]]) u=father[top[u]]; else v=father[top[v]];
     90     }
     91 }
     92 //==================================================
     93 
     94 inline void push_up(int o) {sum[o]=sum[o<<1]+sum[o<<1|1];}
     95 inline void Clr(int o) {clr[o]=1; sum[o]=0;}
     96 inline void push_down(int o) {if (clr[o]) Clr(o<<1),Clr(o<<1|1); clr[o]=0;}
     97 void Modify(int o,int l,int r,int p,int q)
     98 {
     99     if (l==p && r==q)
    100     {
    101         sum[o]=0;
    102         clr[o]=1;
    103         return;
    104     }
    105     push_down(o);
    106     int mid=(l+r)>>1;
    107     if (q<=mid) Modify(o<<1,l,mid,p,q);
    108     if (p>=mid+1) Modify(o<<1|1,mid+1,r,p,q);
    109     if (p<=mid && q>=mid+1) Modify(o<<1,l,mid,p,mid),Modify(o<<1|1,mid+1,r,mid+1,q);
    110     push_up(o);
    111 }
    112 int Query(int o,int l,int r,int p,int q)
    113 {
    114     if (l==p && r==q) return sum[o];
    115     push_down(o);
    116     int mid=(l+r)>>1;
    117     if (q<=mid) return Query(o<<1,l,mid,p,q);
    118     if (p>=mid+1) return Query(o<<1|1,mid+1,r,p,q);
    119     if (p<=mid && q>=mid+1) return Query(o<<1,l,mid,p,mid)+Query(o<<1|1,mid+1,r,mid+1,q);
    120 }
    121 void Build(int o,int l,int r)
    122 {
    123     if (l==r)
    124     {
    125         sum[o]=1; 
    126         return;
    127     }
    128     int mid=(l+r)>>1;
    129     Build(o<<1,l,mid),Build(o<<1|1,mid+1,r);
    130     push_up(o);
    131 }
    132 
    133 //=================================================
    134 void Tree_Modify(int u,int v)
    135 {
    136     while (top[u]!=top[v])
    137     {
    138         Modify(1,1,scc,num[top[u]],num[u]);
    139         u=father[top[u]];
    140     }
    141     Modify(1,1,scc,num[v],num[u]);
    142 }
    143 int Tree_Query(int u,int v) 
    144 {
    145     int ret=0;
    146 
    147     while (top[u]!=top[v])
    148     {
    149          ret+=Query(1,1,scc,num[top[u]],num[u]);
    150         u=father[top[u]];
    151     }
    152     ret+=Query(1,1,scc,num[v],num[u]);
    153     return ret;
    154 }
    155 //=================================================
    156 void Tarjan(int u,int fa)
    157 {
    158     Low[u]=Dfn[u]=++Stamp; Stack[++apex]=u;
    159     for(int i=head[u];i!=-1;i=edge[i].next)
    160         if (edge[i].to!=fa)
    161         {
    162             int v=edge[i].to;
    163             if(!Dfn[v])
    164             {
    165                 Tarjan(v,u);
    166                 Low[u]=Min(Low[u],Low[v]);
    167                 if(Low[v]>Dfn[u])
    168                 {
    169                     scc++;
    170                     while(true) {int x=Stack[apex--]; Belong[x]=scc; if(x==v)break;}
    171                 }
    172             }
    173             else Low[u]=Min(Low[u],Dfn[v]);
    174         }
    175     if(fa<0)
    176     {
    177         scc++;
    178         while(true){int x=Stack[apex--]; Belong[x]=scc;    if(x==u)break;}
    179     }
    180 }
    181 //=================================================
    182 
    183 int main()
    184 {
    185     //freopen("c.in","r",stdin);
    186     Get_Int(n),Get_Int(m);
    187     for (int i=1;i<=m;i++)
    188         Get_Int(u),Get_Int(v),Edge[mp(u,v)]=true,Edge[mp(v,u)]=true;
    189 
    190     for (Q=1;;Q++)
    191     {
    192         Get_Int(Op[Q].type); if (Op[Q].type==-1) break;
    193         Get_Int(Op[Q].u),Get_Int(Op[Q].v);
    194         if (Op[Q].type==0) Edge[mp(Op[Q].u,Op[Q].v)]=false,Edge[mp(Op[Q].v,Op[Q].u)]=false;
    195     }
    196     Q--;
    197     stamp=Stamp=cnt=0;
    198     memset(head,-1,sizeof(head));
    199     memset(vis,false,sizeof(vis));
    200     memset(Low,0,sizeof(Low));
    201     memset(Dfn,0,sizeof(Dfn));
    202 
    203     Build_G();
    204     Tarjan(1,-1);
    205     Clear_G();
    206     for (int i=1;i<=n;i++)
    207         for (int j=head[i];j!=-1;j=edge[j].next)
    208             if (Belong[i]!=Belong[edge[j].to]) 
    209             {
    210                 if (S.count(mp(Belong[i],Belong[edge[j].to]))==1) continue;
    211                 S.insert(mp(Belong[i],Belong[edge[j].to]));
    212                 S.insert(mp(Belong[edge[j].to],Belong[i]));
    213                 V.pb(mp(Belong[i],Belong[edge[j].to]));
    214                 V.pb(mp(Belong[edge[j].to],Belong[i]));
    215             }
    216     
    217 
    218     memset(head,-1,sizeof(head));cnt=0;
    219     for (int i=0;i<V.size();i++) Add(V[i].fi,V[i].se);
    220     father[1]=1;dep[1]=1;
    221     memset(vis,false,sizeof(vis)),Dfs1(1);
    222     memset(vis,false,sizeof(vis)),Dfs2(1,1);
    223     Build(1,1,scc);
    224     for (int i=Q;i>=1;i--)
    225     {
    226         int p=Belong[Op[i].u],q=Belong[Op[i].v];
    227         if (Op[i].type==0)
    228         {
    229             if (p==q) continue;
    230             int t=Lca(p,q);
    231             if (t==p) 
    232             {
    233                 int k=0;
    234                 for (int j=head[t];j!=-1;j=edge[j].next)
    235                     if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
    236 
    237                 Tree_Modify(q,k);
    238                 continue;
    239             }
    240 
    241             if (t==q) 
    242             {
    243                 int k=0;
    244                 for (int j=head[t];j!=-1;j=edge[j].next)
    245                     if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
    246                 Tree_Modify(p,k);
    247                 continue;
    248             }
    249             int r,s;
    250             for (int j=head[t];j!=-1;j=edge[j].next)
    251                 if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {r=edge[j].to; break;}
    252             for (int j=head[t];j!=-1;j=edge[j].next)
    253                 if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {s=edge[j].to; break;}
    254             Tree_Modify(p,r),Tree_Modify(q,s);
    255         } else 
    256         if (Op[i].type==1)
    257         {
    258             if (p==q) {Ans[i]=0; continue;}
    259             int t=Lca(p,q);
    260             if (t==p) 
    261             {
    262                 int k=0;
    263                 for (int j=head[t];j!=-1;j=edge[j].next)
    264                     if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
    265                 Ans[i]=Tree_Query(q,k);
    266                 continue;
    267             }
    268             if (t==q) 
    269             {
    270                 int k=0;
    271                 for (int j=head[t];j!=-1;j=edge[j].next)
    272                     if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
    273                 Ans[i]=Tree_Query(p,k);
    274                 continue;
    275             }
    276             
    277             int r,s;
    278             for (int j=head[t];j!=-1;j=edge[j].next)
    279                 if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {r=edge[j].to; break;}
    280             for (int j=head[t];j!=-1;j=edge[j].next)
    281                 if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {s=edge[j].to; break;}
    282             Ans[i]=Tree_Query(p,r)+Tree_Query(q,s);
    283         }
    284     }
    285     for (int i=1;i<=Q;i++) 
    286         if (Op[i].type==1) Put_Int(Ans[i]);
    287     return 0;
    288 }
    289         
    290     
    傻逼树剖280+系列
  • 相关阅读:
    在bootstrap的column中的formatter里不能传递row参数吗?
    layer弹出层右上角的关闭按钮怎么没有显示
    layer.open获取弹出层的input框的值
    Windows下MongoDB的配置及其远程连接
    MongoDB geonear和文本命令驱动程序2.0
    MongoDB地理空间(2d)索引创建与查询
    图解 MongoDB 地理位置索引的实现原理
    MongoDB的地理位置索引
    MongoDB,使用C#实现2d地理位置检索
    利用MongoDB进行地理坐标查询
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5556777.html
Copyright © 2011-2022 走看看