BZOJ3757 蘋果樹

來源:互聯網
上載者:User

標籤:nbsp   bsp   can   int   namespace   struct   add   clu   scan   

一道挺好的樹上莫隊板子題,可惜存在著作權無法提交了。

這裡給出代碼供大家參考,分塊操作類似於王室聯盟,轉成序列後和普通莫隊一樣。

By:大奕哥

  1 #include<bits/stdc++.h>  2 using namespace std;  3 const int N=1e5+5;  4 int d[N],fa[N][20],bel[N],size[N],dfn[N],col[N],ans[N],p[N],head[N];  5 int n,m,sum,idx,cnt,B,num,top,s[N];  6 bool v[N];  7 struct node{  8     int to,nex;  9 }e[N<<1]; 10 void add(int x,int y) 11 { 12     e[++cnt].nex=head[x];e[cnt].to=y;head[x]=cnt; 13 } 14 struct quer{ 15     int x,y,a,b,id; 16     bool operator<(const quer &b)const{ 17         return bel[x]<bel[b.x]||(bel[x]==bel[b.x]&&dfn[y]<dfn[b.y]); 18     } 19 }q[N]; 20 void dfs(int x) 21 { 22     dfn[x]=++idx;s[++top]=x; 23     for(int i=1;i<=16;++i) 24     fa[x][i]=fa[fa[x][i-1]][i-1]; 25     for(int i=head[x];i;i=e[i].nex) 26     { 27         int y=e[i].to; 28         if(y==fa[x][0])continue; 29         fa[y][0]=x;d[y]=d[x]+1; 30         dfs(y); 31         size[x]+=size[y]; 32         if(size[x]>=B) 33         { 34             num++; 35             for(int k=1;k<=size[x];++k) 36             bel[s[top--]]=num; 37             size[x]=0; 38         } 39     } 40     size[x]++; 41 } 42 int lca(int x,int y) 43 { 44     if(d[x]<d[y])swap(x,y); 45     int tmp=d[x]-d[y]; 46     for(int i=0;i<=16;++i) 47     if(tmp&(1<<i))x=fa[x][i]; 48     for(int i=16;i>=0;--i) 49     { 50         if(fa[x][i]!=fa[y][i]) 51         { 52             x=fa[x][i]; 53             y=fa[y][i]; 54         } 55     } 56     return x==y?x:fa[x][0]; 57 } 58 void reverse(int x) 59 { 60     if(!v[x]){v[x]=1;p[col[x]]++;if(p[col[x]]==1)sum++;} 61     else {v[x]=0;p[col[x]]--;if(p[col[x]]==0)sum--;} 62     return; 63 } 64 void solve(int x,int y) 65 { 66     while(x!=y) 67     {     68         if(d[x]<d[y])swap(x,y); 69         reverse(x);x=fa[x][0]; 70     } 71     return; 72 } 73 int main() 74 { 75     scanf("%d%d",&n,&m); 76     B=sqrt(n);int x,y,rt; 77     for(int i=1;i<=n;++i)scanf("%d",&col[i]); 78     for(int i=1;i<=n;++i) 79     { 80         scanf("%d%d",&x,&y); 81         if(!x)rt=y;else if(!y)rt=x; 82         else add(x,y),add(y,x); 83     } 84     dfs(rt);num++; 85     while(top)bel[s[top--]]=num; 86     for(int i=1;i<=m;++i) 87     { 88         scanf("%d%d",&q[i].x,&q[i].y); 89         if(dfn[q[i].x]>dfn[q[i].y])swap(q[i].x,q[i].y); 90         q[i].id=i; 91         scanf("%d%d",&q[i].a,&q[i].b); 92     } 93     sort(q+1,q+1+m); 94     int z=lca(q[1].x,q[1].y); 95     solve(q[1].x,q[1].y); 96     reverse(z);ans[q[1].id]=sum; 97     if(p[q[1].a]&&p[q[1].b]&&q[1].a!=q[1].b)ans[q[1].id]--; 98     reverse(z); 99     for(int i=2;i<=m;++i)100     {101         int z=lca(q[i].x,q[i].y);102         solve(q[i-1].x,q[i].x);103         solve(q[i-1].y,q[i].y);104         reverse(z);ans[q[i].id]=sum;105         if(p[q[i].a]&&p[q[i].b]&&q[i].a!=q[i].b)ans[q[i].id]--;106         reverse(z);107     }108     for(int i=1;i<=m;++i)printf("%d\n",ans[i]);109     return 0;110 }

 

BZOJ3757 蘋果樹

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.