【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.mzph.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…