【Foreign】采蘑菇 [點分治]

采蘑菇

Time Limit: 20 Sec??Memory Limit: 256 MB

Description

  

Input

  

Output

  

Sample Input

  5
  1 2 3 2 3
  1 2
  1 3
  2 4
  2 5

Sample Output

  10
  9
  12
  9
  11

HINT

  

Main idea

  詢問從以每個點為起始點時,各條路徑上的顏色種類的和。

Solution

  我們看到題目,立馬想到了O(n^2)的做法,然后從這個做法研究一下本質,我們確定了可以以點分治作為框架。

  我們先用點分治來確定一個center(重心)。然后計算跟這個center有關的路徑。設現在要統計的是經過center,對x提供貢獻的路徑。

  我們先記錄一個記錄Sum[x]表示1~i-1子樹中 顏色x 第一次出現的位置的那個點 的子樹和,然后我們就利用這個Sum來解題。

  我們顯然可以分兩種情況來討論:

  (1)統計center->x出現顏色的貢獻
    顯然,這時候,對于center->x這一段,直接像O(n^2)做法那樣記錄一個color表示到目前為止出現的顏色個數,然后加一下即可。再記錄一個record表示當前可有的貢獻和,一旦出現過一個顏色,那么這個顏色在1~i-1子樹上出現第一次以下的點,對于x就不再提供貢獻了,record減去Sum[這個顏色],然后這樣深搜往下計算即可。

  (2)統計center->x沒出現過的顏色的貢獻
    顯然,對于center->x上沒出現過的顏色,直接往下深搜,一開始為record為(All - Sum[center]),一旦出現了一個顏色,record則減去這個Sum。同樣表示不再提供貢獻即可。

  我們這樣做就可以求出每個子樹前綴對于其的貢獻了,倒著再做一邊即可求出全部的貢獻。統計x的時候,順便統計一下center。可以滿足效率,成功AC這道題。

Code

  1 #include<iostream>  
  2 #include<algorithm>  
  3 #include<cstdio>  
  4 #include<cstring>  
  5 #include<cstdlib>  
  6 #include<cmath>  
  7 using namespace std;
  8 
  9 const int ONE = 600005;
 10 const int INF = 214783640;
 11 const int MOD = 1e9+7;
 12 
 13 int n,x,y;
 14 int Val[ONE];
 15 int next[ONE],first[ONE],go[ONE],tot;
 16 int vis[ONE];
 17 int Ans[ONE],Sum[ONE];
 18 int All;
 19 
 20 
 21 int get()
 22 { 
 23         int res,Q=1;    char c;
 24         while( (c=getchar())<48 || c>57)
 25         if(c=='-')Q=-1;
 26         if(Q) res=c-48; 
 27         while((c=getchar())>=48 && c<=57) 
 28         res=res*10+c-48; 
 29         return res*Q; 
 30 }
 31 
 32 void Add(int u,int v)
 33 {
 34         next[++tot]=first[u];    first[u]=tot;    go[tot]=v;
 35         next[++tot]=first[v];    first[v]=tot;    go[tot]=u;
 36 }
 37 
 38 namespace Point
 39 {
 40         int center;
 41         int Stack[ONE],top;
 42         int total,Max,center_vis[ONE];
 43         int num,V[ONE];
 44         
 45         struct power
 46         {
 47             int size,maxx;
 48         }S[ONE];
 49         
 50         void Getsize(int u,int father)
 51         {
 52             S[u].size=1;
 53             S[u].maxx=0;
 54             for(int e=first[u];e;e=next[e])
 55             {
 56                 int v=go[e];
 57                 if(v==father || center_vis[v]) continue;
 58                 Getsize(v,u);
 59                 S[u].size += S[v].size;
 60                 S[u].maxx = max(S[u].maxx,S[v].size);
 61             }
 62         }
 63              
 64         void Getcenter(int u,int father,int total)
 65         {
 66             S[u].maxx = max(S[u].maxx,total-S[u].size);
 67             if(S[u].maxx < Max)
 68             {
 69                 Max = S[u].maxx;
 70                 center = u;
 71             }
 72                
 73             for(int e=first[u];e;e=next[e])
 74             {
 75                 int v=go[e];
 76                 if(v==father || center_vis[v]) continue;
 77                 Getcenter(v,u,total);
 78             }
 79         }
 80         
 81         void Ad_sum(int u,int father)
 82         {
 83             if(!vis[Val[u]])
 84             {
 85                 Stack[++top] = Val[u];
 86                 All += S[u].size;    Sum[Val[u]] += S[u].size;
 87             }
 88             vis[Val[u]]++;
 89             for(int e=first[u];e;e=next[e])
 90             {
 91                 int v=go[e];
 92                 if(v==father || center_vis[v]) continue;
 93                 Ad_sum(v,u);
 94             }
 95             vis[Val[u]]--;
 96         }
 97 
 98         void Calc_in(int u,int father,int center,int Size,int f_time,int record)
 99         {
100             if(!vis[Val[u]]) f_time++, record += Size, record -= Sum[Val[u]];
101             Ans[u] += record;    Ans[center]+=f_time;
102             Ans[u] += f_time;    vis[Val[u]] ++;
103             for(int e=first[u];e;e=next[e])
104             {
105                 int v=go[e];
106                 if(v==father || center_vis[v]) continue;
107                 Calc_in(v,u,center,Size,f_time,record);
108             }
109             vis[Val[u]] --;
110         }
111         
112         void Calc_not(int u,int father,int record)
113         {
114             if(!vis[Val[u]]) record -= Sum[ Val[u] ];
115             Ans[u] += record;    vis[Val[u]] ++;
116             for(int e=first[u];e;e=next[e])
117             {
118                 int v=go[e];
119                 if(v==father || center_vis[v]) continue;
120                 Calc_not(v,u,record);
121             }
122             vis[Val[u]] --;
123         }
124         
125         void Dfs(int u)
126         {
127             Max = n;
128             Getsize(u,0);
129             Getcenter(u,0,S[u].size);
130             Getsize(center,0);
131             center_vis[center] = 1;
132             
133             int num=0; for(int e=first[center];e;e=next[e]) if(!center_vis[go[e]]) V[++num]=go[e];
134             
135             for(int i=1;i<=num;i++)
136             {
137                 int v=V[i];
138                 int Size = S[center].size - S[v].size - 1;
139                 vis[Val[center]] = 1;
140                 Calc_in(v,center,center, Size,1,All - Sum[Val[center]] + Size);
141                 vis[Val[center]] = 0;
142                 Ad_sum(v,center);
143             }
144             while(top) Sum[Stack[top--]]=0;    All=0;
145             
146             for(int i=num;i>=1;i--)
147             {
148                 int v=V[i];
149                 vis[Val[center]] = 1;
150                 Calc_not(v,center, All-Sum[Val[center]]);
151                 vis[Val[center]] = 0;
152                 Ad_sum(v,center);
153             }
154             
155             while(top) Sum[Stack[top--]]=0;    All=0;
156             for(int e=first[center];e;e=next[e])
157             {
158                 int v=go[e];
159                 if(center_vis[v]) continue;
160                 Dfs(v);
161             }
162         }
163         
164 }
165 
166 int main()
167 {      
168         n=get();
169         for(int i=1;i<=n;i++)    Val[i]=get();
170 
171         for(int i=1;i< n;i++)
172         {
173             x=get();    y=get();
174             Add(x,y);
175         }
176         
177         Point:: Dfs(1);
178         for(int i=1;i<=n;i++)
179             printf("%d\n",Ans[i]+1);
180 }
View Code

?

轉載于:https://www.cnblogs.com/BearChild/p/6517325.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457043.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457043.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457043.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言迷宮游戲怎么存放坐標,求解迷宮問題(c語言,很詳細哦

《求解迷宮問題(c語言,很詳細哦》由會員分享&#xff0c;可在線閱讀&#xff0c;更多相關《求解迷宮問題(c語言,很詳細哦(5頁珍藏版)》請在人人文庫網上搜索。1、求迷宮問題就是求出從入口到出口的路徑。在求解時 , 通常用的是 “窮舉求解”的方法 ,即從入口出發 ,順某一方向向…

模塊概述

概述 目前代碼比較少&#xff0c;寫在一個文件中還體現不出什么缺點&#xff0c;但是隨著代碼量越來越多&#xff0c; 代碼就越來越難以維護 為了解決難以維護的問題&#xff0c;我們把很多相似功能的函數分組&#xff0c;分別放到不同的文件中取。這樣每個文件所包含的內容相…

【MySQL】PREPARE 的應用

簡單的用set或者declare語句定義變量&#xff0c;然后直接作為sql的表名是不行的&#xff0c;mysql會把變量名當作表名。在其他的sql數據庫中也是如此&#xff0c;mssql的解決方法是將整條sql語句作為變量&#xff0c;其中穿插變量作為表名&#xff0c;然后用sp_executesql調用…

簡歷要求中“ 扎實的JAVA基礎”的學習方法

最近在頭條看到一篇關于Java基礎學習的文章&#xff0c;感覺寫的很不錯&#xff0c;分享一下&#xff0c;希望對大家有幫助 什么東西算作Java基礎&#xff1f;學到什么程度才算扎實&#xff1f; 這些問題的答案&#xff0c;LZ已經用文言文告訴你了&#xff0c;咳咳&#xff0c;…

C++11 tuple的使用

多少分轉載于:https://www.cnblogs.com/DswCnblog/p/6524832.html

c語言程序設計貪吃蛇需求分析,C語言編程新手入門基礎進階學習!貪吃蛇小游戲演示和說明...

C語言是面向過程的&#xff0c;而C&#xff0b;&#xff0b;是面向對象的設計貪吃蛇游戲的主要目的是讓大家夯實C語言基礎&#xff0c;訓練編程思維&#xff0c;培養解決問題的思路&#xff0c;領略多姿多彩的C語言。游戲開始后&#xff0c;會在中間位置出現一條只有三個節點的…

解決bash: mysql: command not found 的方法【linux mysql命令 】

linux下&#xff0c;在mysql正常運行的情況下&#xff0c;輸入mysql提示&#xff1a; mysql command not found 遇上-bash: mysql: command not found的情況別著急&#xff0c;這個是因為/usr/local/bin目錄下缺失mysql導致&#xff0c;只需要以下方法即可以解決&#xff1a; …

堆和棧的區別(經典干貨)

一、預備知識—程序的內存分配 一個由C/C編譯的程序占用的內存分為以下幾個部分 1、棧區&#xff08;stack&#xff09;— 由編譯器自動分配釋放 &#xff0c;存放函數的參數值&#xff0c;局部變量的值等。其 操作方式類似于 數據結構 中的棧。 2、堆區&#xff08;he…

Strus2中關于ValueStack詳解

什么是ValueStack 它是一個接口com.opensymphony.xwork2.util.ValueStack。我們使用它是將其做為一個容器&#xff0c;用于攜帶action數據到頁面。在頁面上通過ognl表達式獲取數據。 valueStack主要是將action數據攜帶到頁面上&#xff0c;通過ognl獲取數據 1.ValueStack有一個…

Airbnb React/JSX 編碼規范

Airbnb React/JSX 編碼規范算是最合理的React/JSX編碼規范之一了內容目錄基本規范Class vs React.createClass vs stateless命名聲明模塊代碼對齊單引號還是雙引號空格屬性Refs引用括號標簽函數/方法模塊生命周期isMountedBasic Rules 基本規范每個文件只寫一個模塊.但是多個無…

Mysql數據庫使用總結

mysql數據庫使用總結 本文主要記錄一些mysql日常使用的命令&#xff0c;供以后查詢。 1.更改root密碼 mysqladmin -uroot password yourpassword 2.遠程登陸mysql服務器 mysql -uroot -p -h192.168.137.10 -P3306 3.查詢數據庫 show databases; 4.進入某個數據庫 use databa…

c語言遞歸漢諾塔次數,漢諾塔問題(C語言經典遞歸問題(一))

把A桿上的金盤全部移到C桿上&#xff0c;并仍保持原有順序疊好。操作規則&#xff1a;每次只能移動一個盤子&#xff0c;并且在移動過程中三根桿上都始終保持大盤在下&#xff0c;小盤在上&#xff0c;操作過程中盤子可以置于A、B、C任一桿上。思路&#xff1a;圖解&#xff1a…

Eclipes導入的項目中的中文都是亂碼的解決辦法

把項目導入Eclipse時&#xff0c;里邊的中文全是亂碼&#xff0c;試了很多方法&#xff0c;最終總結一下&#xff01; eclipse之所以會出現亂碼問題是因為eclipse編輯器選擇的編碼規則是可變的。一般默認都是UTF-8或者GBK&#xff0c;當從外部導入的一個工程時&#xff0c;如果…

理解瀏覽器是如何加載及渲染網頁的

先上圖&#xff0c;我們再慢慢解釋&#xff0c;這圖就是瀏覽器加載網頁的一個過程 當我們在瀏覽器輸入一個地址&#xff08;比如:http://toadw.cn&#xff09;,那么點擊回車后&#xff0c;瀏覽器是如何加載網頁的呢&#xff1f; 加載過程 一開始瀏覽器是不知道你輸入的http://t…

CentOS下的Mysql的安裝和使用

1.使用安裝命令 &#xff1a;yum -y install mysql mysql-server mysql-devel 安裝完成卻發現Myserver安裝缺失&#xff0c;在網上找原因&#xff0c;原來是因為CentOS 7上把MySQL從默認軟件列表中移除了&#xff0c;用MariaDB來代替&#xff0c;所以這導致我們必須要去官網上…

NOIP模擬題——神秘大門

【題目描述】最近小K大牛經過調查發現&#xff0c;在WZland的最南方——WZ Antarctica 出現了奇怪的磁場反應。為了弄清楚這一現象&#xff0c;小K 大牛親自出馬&#xff0c;來到了WZ Antarctica。小K大牛發現WZ Antarctica 出現了一道神秘的大門。人總有好奇心&#xff0c;小K…

大學c語言程序設計大賽,關于舉辦寧夏大學第二屆C語言程序設計大賽的通知

各學院&#xff1a;根據學校《關于進一步加強基礎課教學改革的意見》(寧大校發〔2008〕178號)、《關于加強學生創新精神和創新能力培養的實施意見》(寧大校發〔2008〕75號)的有關文件精神&#xff0c;經研究決定舉辦寧夏大學第二屆C語言程序設計大賽&#xff0c;從中選拔出優秀…

Android中創建自己的對話框

Activities提供了一種方便管理的創建、保存、回復的對話框機制&#xff0c;例如 onCreateDialog(int), onPrepareDialog(int, Dialog), showDialog(int), dismissDialog(int)等方法&#xff0c;如果使用這些方法的話&#xff0c;Activity將通過getOwnerActivity()方法返回該Act…

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11

搭建Django2.0Python3MySQL5時同步數據庫時報錯&#xff1a; django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None 解決辦法&#xff1a; 找到Python安裝路勁下的Python36-32\Lib\site-packages\django\db\backend…

一件很好笑的事情

我是一個比較習慣努力學習的人&#xff0c; 我也會去學習各種可能與我有交集的知識&#xff0c; 就在這幾天&#xff0c;我看到以前的一個android網絡培訓學校開辦了C/C的培訓&#xff0c;這是挺好的事&#xff0c; 但是看他們的文件&#xff0c;我就奇怪了。 這份文件&#xf…