日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UOJ #579. 树上的颜色

發(fā)布時間:2024/4/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UOJ #579. 树上的颜色 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【題目描述】:給出一棵有N個點的有根樹,結(jié)點編號為1,2,3,……,N,根結(jié)點編號為1,編號為i的結(jié)點涂上顏色Ci。現(xiàn)在有M個詢問,每個詢問要求求出以結(jié)點u為根的子樹上涂有此種顏色的結(jié)點個數(shù)不小于k的顏色個數(shù)有多少。 【輸入描述】:第一行包含兩個正整數(shù)N和M。第二行包含N個正整數(shù),C1,C2,…,CN。接下來的N-1行每行有兩個正整數(shù)x和y,表示結(jié)點x和y有邊相連。再接下來的M行每行有兩個正整數(shù)u和k,表示一個詢問。 【輸出描述】:輸出M行,每行一個非負整數(shù),對應(yīng)每個詢問的答案。 【樣例輸入1】:4 1 1 2 3 4 1 2 2 3 3 4 1 1【樣例輸出1】:4【樣例輸入2】:8 5 1 2 2 3 3 2 3 3 1 2 1 5 2 3 2 4 5 6 5 7 5 8 1 2 1 3 1 4 2 3 5 3【樣例輸出2】:2 2 1 0 1【時間限制、數(shù)據(jù)范圍及描述】:時間:1s 空間:256M對于10%的數(shù)據(jù),N≤100,M≤100,Ci≤100;對于30%的數(shù)據(jù),N≤500,M≤100;對于60%的數(shù)據(jù),N≤2000,M≤100000;對于100%的數(shù)據(jù),N≤100000,M≤100000,Ci≤100000。本題用color[i]統(tǒng)計第i鐘顏色的數(shù)量,用sum[i]統(tǒng)計顏色數(shù)量為i,i+1,i+2,……的顏色個數(shù)。 設(shè)要加入一個點,其顏色為x,則sum[color[x]+1]增加1,sum的其他值不變,同時color[x]++即可。同理,刪去一個點,sum[color[x]–]–即可。這時sum就是最終答案。 然而這時時間復雜度是O(N^2)的,還需進一步優(yōu)化,于是看到區(qū)間修改和統(tǒng)計我們想到了莫隊. 但這里要更復雜一些,因為是在樹上,所以需要用樹上莫隊,將樹上的點按照dfs序拉成一個序列,再用莫隊即可求解。Code: #include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<cstdlib> #include<algorithm> #include<ctime> using namespace std; const int N=100005; int n,m,block,cnt,c[N],s[N],t[N],dfn,re[N],colour[N],num[N],sum[N],ans[N],head[N]; struct Node{int u,v,nxt; }edge[N*2]; struct node{int l,r,k,id; }q[N]; void Push(int u,int v){++cnt;edge[cnt].u=u;edge[cnt].v=v;edge[cnt].nxt=head[u];head[u]=cnt; } void dfs(int u,int fa){s[u]=++dfn;c[dfn]=colour[u];for (int i=head[u];i;i=edge[i].nxt){int v=edge[i].v;if(v==fa){continue;}dfs(v,u);}t[u]=dfn; } bool cmp(node a,node b){return (a.l/block)^(b.l/block)?a.l<b.l:(((a.l/block)&1)?a.r<b.r:a.r>b.r); } int main(){int x,y,u,k;scanf("%d%d",&n,&m);block=sqrt(n);for(int i=1;i<=n;i++){scanf("%d",&colour[i]);}for(int i=1;i<n;i++){scanf("%d%d",&x,&y);Push(x,y);Push(y,x);}dfs(1,0);for(int i=1;i<=m;i++){scanf("%d%d",&u,&k);q[i]=(node){s[u],t[u],k,i};}sort(q+1,q+1+m,cmp);int L=1,R=0;for(int i=1;i<=m;i++){while(q[i].l<L){L--,num[c[L]]++,sum[num[c[L]]]++;}while(q[i].l>L){sum[num[c[L]]]--,num[c[L]]--,L++;}while(q[i].r>R){R++,num[c[R]]++,sum[num[c[R]]]++;}while(q[i].r<R){sum[num[c[R]]]--,num[c[R]]--,R--;}ans[q[i].id]=sum[q[i].k];}for(int i=1;i<=m;i++){printf("%d\n",ans[i]);}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/ukcxrtjr/p/11522098.html

總結(jié)

以上是生活随笔為你收集整理的UOJ #579. 树上的颜色的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。