题目大意:

给定n个点的无根树,树上每个点都有一个非负的点权.

树上的路径的价值定义为树上路径的点权和-树上路径的点权最大值;

现在给定一个参数P询问有多少条路径的价值是P的倍数(注意单点也算路径,路径不重复算)

这个题一眼就知道是点分治之类的鬼东西,第一眼觉得长得想聪聪可可,然后直接开了一个桶码起点分治,

但是有一个尴尬的地方就是在处理经过一个点的路径的时候我发现我不知道该怎么O(size)的转移,因为路径

上的最大值是不知道的,所以我考场上只打一个O(size^2)的转移(暴力枚举组合...),于是复杂度变成了n^2*logn

还不如n^2暴力...于是实力滚粗

好吧,我们想一想我们处理这个问题的瓶颈就是如何处理经过一个点的路径

我们又发现这个问题的瓶颈是处理这个max,由于不知道max所以我们只能暴力枚举组合

于是冥冥中我就蠢了,听大佬讲题的第一句话就想把自己的脸打肿

我们考虑让max变的有序起来

比如说我们把一这个点为根能遍历到的点按照max从小到达sort再依次加入与已有的边进行组合

这样有什么好处呢???

我们发现这样你每把当前这条边加入和原来的边进行组合的时候,由于已经按max排过序了,

他和别的边组合的max,就是他自己的max,这样组合的max的边就已知了,

这样你就可以直接查询桶了,然后加完后再把他自己的权值和放入桶中,和聪聪可可有点像

复杂度n*logn^2;

这题嘴巴AC很容易,但是由于他记的是点权,所以在处理的时候需要一些不同于边权的操作,所以在

摸爬滚打很久之后才AC

附上代码:

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<set>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#define lson num<<1
#define rson num<<1|1
#define int long long
using namespace std;
typedef long long ll;
const int N=300050;
const int Inf=2147483647;
int gi()
{
int x=0,flag=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*flag;
}
int head[N],nxt[N],to[N],P,n,ans;
int size[N],f[N],dis[N],maxn[N],vis[N];
int root,SIZE,v[N],tot,cnt,tong[10000050],used[N];
struct data{
int dis,maxn,id;
}w[N];
bool cmp(const data & a,const data &b){
return a.maxn<b.maxn;
}
void getroot(int x,int fa){
size[x]=1;f[x]=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y!=fa&&!vis[y]){
getroot(y,x);
size[x]+=size[y];
f[x]=max(f[x],size[y]);
}
}
f[x]=max(f[x],SIZE-size[x]);
if(f[x]<f[root]) root=x;
}
void getdeep(int x,int fa){
w[++tot]=(data){dis[x],maxn[x],x};
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y!=fa&&!vis[y]){
dis[y]=(dis[x]+v[y])%P;
maxn[y]=max(maxn[x],v[y]);
getdeep(y,x);
}
}
}
int cal(int x,int y){
int ret=0,sum=0,tt=0;
tot=0;dis[x]=(v[x]+y)%P,maxn[x]=max(v[x],y);
getdeep(x,0);sort(w+1,w+1+tot,cmp);
//if(y) cout<<"是要减去的"<<' ';
//cout<<x<<"的子树中:"<<endl;
if(y==0) y=v[x];
for(int i=1;i<=tot;i++){
//cout<<w[i].dis<<' '<<w[i].maxn<<' '<<w[i].id<<"need:";
int now=(P+w[i].maxn+y-w[i].dis)%P;
//cout<<now<<' '<<tong[now]<<endl;
ret+=tong[now];
tong[w[i].dis]++;
used[++sum]=w[i].dis;
}
//cout<<"产生"<<ret<<"的贡献"<<endl;
//cout<<"---------"<<endl;
for(int i=1;i<=sum;i++) tong[used[i]]--;
return ret;
}
void work(int x){
ans+=cal(x,0);vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(!vis[y]){
ans-=cal(y,v[x]);
SIZE=size[y];root=0;
getroot(y,root);work(root);
}
}
}
void lnk(int x,int y){
to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
to[++cnt]=x,nxt[cnt]=head[y],head[y]=cnt;
}
main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
n=gi(),P=gi();
for(int i=1;i<n;i++){
int x=gi(),y=gi();lnk(x,y);
}
for(int i=1;i<=n;i++) v[i]=gi();
root=0;f[0]=Inf;SIZE=n;getroot(1,0);work(root);ans+=n;
printf("%lld\n",ans);
}

某次送温暖考试的 c题的更多相关文章

  1. bzoj4693: 雪中送温暖

    Description 每年的1月10日是温暖节,在这一天,化身出题人的C_SUNSHINE将会给OIer们送温暖.OIer们只要在门口放上一个 仙人掌,就能在早上的某个时刻听到门外传来一声:“开门, ...

  2. 中国MOOC_零基础学Java语言_期末考试的编程题_1二进制的前导的零

    期末考试的编程题 返回   这是期末考试的编程题,在60分钟内,你可以多次提交,直到正确为止. 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止 ...

  3. 考试宝典-真题园安卓AppV2.1.0新版发布啦,全新界面,全新体验,全面适配Android 5.0&6.0系统!

    真题园移动客户端是真题园网 http://www.zhentiyuan.com 旗下的一款学习考试应用App. 1.全新适配Android5.0.6.0系统,重新优化架构网络通信模块. 2.全新清爽U ...

  4. C语言考试解答十题

    学院比较奇葩,大一下期让学的VB,这学期就要学C++了,然后在开学的前三个周没有课,就由老师讲三个周的C语言,每天9:30~11:30听课,除去放假和双休日,实际听课时间一共是12天*2小时,下午是1 ...

  5. OCP 认证考试报名费技巧题库051052053解析合格线

    本人于2017年4月22日通过参加OCP考试,第一次参加,一天之内考了三门,三门一次性通过,052 - 95% ,053 - 86% ,051 - 100% 一.关于考试考试报名费: 052:158$ ...

  6. HDU 2093 考试排名 模拟题

    解题报告: 题目描述:写一个程序给一个编程考试C++实时提交系统排名,给你的数据是题目的总数,每次错误提交罚的时间分,每位用户的姓名,然后是输入用户每题的完成情况,有一下几种情况,第一,输入只有一个正 ...

  7. 2019PAT春季考试第4题 7-4 Structure of a Binary Tree (30 分)

    题外话:考试的时候花了一个小时做了27分,由于Siblings这个单词不知道意思,所以剩下的3分就没去纠结了,后来发现单词是兄弟的意思,气哭~~ 这道题的麻烦之处在于如何从一个字符串中去找数字.先首先 ...

  8. [考试]NOIP2015模拟题2

    // 此博文为迁移而来,写于2015年7月22日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w72i.html 1.总 ...

  9. [HNOI2009]双递增序列(洛谷P4728)+小烈送菜(内部训练题)——奇妙的dp

    博主学习本题的经过嘤嘤嘤: 7.22 : 听学长讲(一知半解)--自己推(推不出来)--网上看题解--以为自己会了(网上题解是错的)--发现错误以后又自己推(没推出来)--给学长发邮件--得到正确解法 ...

随机推荐

  1. Self Hosting WebServer 的几种方式

    写在前面: IIS是Windows平台非常关键的组件,它是微软自带的Web服务器,可以很方便的帮助我们运行起一个网站,WebApi等服务,提供给外部来访问.即使它被很多java或者ruby的同学各种鄙 ...

  2. PHP面向对象之const常量修饰符

    在PHP中定义常量是通过define()函数来完成的,但在类中定义常量不能使用define(),而需要使用const修饰符.类中的常量使用const定义后,其访问方式和静态成员类似,都是通过类名或在成 ...

  3. cinder块存储 后端采用lvm、nfs安装配置

    #cinder块存储 后端采用lvm.nfs安装配置 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html #cinder ...

  4. RabbitMQ Cluster群集安装配置

    #RabbitMQ Cluster群集安装配置 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ########## ...

  5. gitlab环境搭建

    企业级的git管理程序.最好用的之一吧.估计其它的也得叫之二. 怎么搭建呢? 2G以上配置的机器才可以搞. . 如下 安装需要注意的是.如果开了80端口,8080的需要修改配置文件  下面会提到 1. ...

  6. dom4j详解

    Dom4j下载及使用Dom4j读写XML简介要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:htt ...

  7. 基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多

    通过多次爬坑,发现了这些监听滚动来加载更多的组件的共同点, 因为这些加载更多的方法是绑定在需要加载更多的内容的元素上的, 所以是进入页面则直接触发一次,当监听到滚动事件之后,继续加载更多, 所以对于无 ...

  8. PHP-学习之路1

    相信入职快有5个月了,目前项目做过HIS,zySystem,ComStoreSystem当然今天不是来介绍的,后期直到第四个月后APP护身宝经理拍板今后也就是明年正式交于我们团队接手与扩展,运维.虽然 ...

  9. 使用NPOI读取Excel数据到DataTable

    如今XML文件的存储格式大行其道,可是也不是适用于全部情况,非常多单位的数据交换还是使用Excel的形式.这就使得我们须要读取Excel内的数据.载入到程序中进行处理.可是如何有效率的读取,如何使程序 ...

  10. 天津政府应急系统之GIS一张图(arcgis api for flex)解说(三)显示地图坐标系模块

    config.xml文件的配置例如以下: 1 2 <widget left="3" bottom="3" config="widgets/Coo ...