BZOJ4012 [HNOI2015]开店 (动态点分治)
Description
风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到
Input
第一行三个用空格分开的数 n、Q和A,表示树的大小、开店的方案个数和妖
Output
对于每个方案,输出一行表示方便值。
Sample Input
0 0 7 2 1 4 7 7 7 9
1 2 270
2 3 217
1 4 326
2 5 361
4 6 116
3 7 38
1 8 800
6 9 210
7 10 278
8 9 8
2 8 0
9 3 1
8 0 8
4 2 7
9 7 3
4 7 0
2 2 7
3 2 1
2 3 4
Sample Output
957
7161
9466
3232
5223
1879
1669
1282
0
HINT
满足 n<=150000,Q<=200000。对于所有数据,满足 A<=10^9
题解
这题正解是动态点分治(不过据说主席树+树链剖分跑得更快?)
如果不知道什么是动态点分的可以去看看幻想乡的战略游戏->蒟蒻的题解
这一道题,我们考虑对于每一个点分树上的点维护什么。我们记录三个值,$sz_0$表示子树内的点数之和,$sz_1$表示子树内所有点到其的距离之和,$sz_2$表示子树内所有点到其父亲的距离之和。那么考虑我们在跳点分树的时候要如何维护答案呢?很明显$sz_1[u]+\sum sz_1[fa]-sz_2[p]+(sz_0[fa]-sz_0[p])*dist(fa,u)$就是在点分树上与$u$的$LCA$是$fa$的所有点的距离之和,其中$fa$为$p$的父亲,$p$为从$u$不断跳父亲直到根,那么只要不断枚举$fa$,并不断往上跳并维护答案就可以了。
然而上面只是为了方便理解,因为具体的计算不是这样的。我们对于$u$点内部的贡献可以直接计算,然后考虑往上跳。在上述的式子中如果一个点$p$有$fa$,那么答案就要减去$sz_0[p]*dist(fa,u)+sz_2[p]$,如果一个点不是$u$那么答案就要加上$sz_0[p]+dist(p,u)$,然后每一个点都要加上自己的$sz_1$。按这个规律在跳点分树的时候不断加就好了
然后考虑怎么在$[l,r]$之内,很明显可以搞一个差分,把每一个节点在点分树上的子树内的所有年龄的距离之和加起来,在做前缀和,那么在年龄$[l,r]$的人数就是$[1,r]-[1,l-1]$
1 //minamoto 2 #include<cstdio> 3 #include<iostream> 4 #include<cstring> 5 #include<vector> 6 #include<algorithm> 7 #define ll long long 8 #define N 150005 9 using namespace std; 10 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 11 char buf[1<<21],*p1=buf,*p2=buf; 12 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 13 inline int read(){ 14 #define num ch-'0' 15 char ch;bool flag=0;int res; 16 while(!isdigit(ch=getc())) 17 (ch=='-')&&(flag=true); 18 for(res=num;isdigit(ch=getc());res=res*10+num); 19 (flag)&&(res=-res); 20 #undef num 21 return res; 22 } 23 char sr[1<<21],z[20];int C=-1,Z; 24 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 25 inline void print(ll x){ 26 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 27 while(z[++Z]=x%10+48,x/=10); 28 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 29 } 30 int head[N],Next[N<<1],ver[N<<1],edge[N<<1]; 31 int n,tot,val[N],q,maxn; 32 int st[N<<1][19],d[N],dfn[N],num,bin[25],tp,logn[N<<1]; 33 inline void add(int u,int v,int e){ 34 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 35 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=e; 36 } 37 inline void ST(){ 38 for(int j=1;j<=tp;++j) 39 for(int i=1;i+bin[j]-1<=(n<<1);++i) 40 st[i][j]=min(st[i][j-1],st[i+bin[j-1]][j-1]); 41 } 42 void dfs1(int u,int fa){ 43 st[dfn[u]=++num][0]=d[u]; 44 for(int i=head[u];i;i=Next[i]){ 45 int v=ver[i]; 46 if(v==fa) continue; 47 d[v]=d[u]+edge[i],dfs1(v,u),st[++num][0]=d[u]; 48 } 49 } 50 int fa[N],sz[N],son[N],size,rt;bool vis[N]; 51 void dfs2(int u,int fa){ 52 sz[u]=1,son[u]=0; 53 for(int i=head[u];i;i=Next[i]){ 54 int v=ver[i]; 55 if(vis[v]||v==fa) continue; 56 dfs2(v,u),sz[u]+=sz[v],cmax(son[u],sz[v]); 57 } 58 cmax(son[u],size-sz[u]); 59 if(son[u]<son[rt]) rt=u; 60 } 61 inline ll dis(int a,int b){ 62 if(dfn[a]>dfn[b]) a^=b^=a^=b; 63 int k=logn[dfn[b]-dfn[a]+1]; 64 return d[a]+d[b]-(min(st[dfn[a]][k],st[dfn[b]-bin[k]+1][k])<<1); 65 } 66 struct node{ 67 int val;ll sz[3]; 68 node(int a=0,ll b=0,ll c=0,ll d=0){val=a,sz[0]=b,sz[1]=c,sz[2]=d;} 69 inline bool operator <(const node &b)const 70 {return val<b.val;} 71 }; 72 vector<node> sta[N]; 73 void dfs3(int u,int f,int rt){ 74 sta[rt].push_back(node(val[u],1,dis(u,rt),fa[rt]?dis(u,fa[rt]):0)); 75 for(int i=head[u];i;i=Next[i]){ 76 int v=ver[i]; 77 if(v==f||vis[v]) continue; 78 dfs3(v,u,rt); 79 } 80 } 81 void dfs4(int u){ 82 vis[u]=true; 83 dfs3(u,0,u);sta[u].push_back(node(-1,0,0,0)); 84 sort(sta[u].begin(),sta[u].end()); 85 for(int i=0,j=sta[u].size();i<j-1;++i) 86 sta[u][i+1].sz[0]+=sta[u][i].sz[0], 87 sta[u][i+1].sz[1]+=sta[u][i].sz[1], 88 sta[u][i+1].sz[2]+=sta[u][i].sz[2]; 89 for(int i=head[u];i;i=Next[i]){ 90 int v=ver[i]; 91 if(vis[v]) continue; 92 rt=0,size=sz[v]; 93 dfs2(v,0),fa[rt]=u,dfs4(rt); 94 } 95 } 96 inline node query(int id,int l,int r){ 97 if(id==0) return node(); 98 vector<node>::iterator it1=upper_bound(sta[id].begin(),sta[id].end(),node(r,0,0,0));--it1; 99 vector<node>::iterator it2=upper_bound(sta[id].begin(),sta[id].end(),node(l-1,0,0,0));--it2; 100 return node(0,it1->sz[0]-it2->sz[0],it1->sz[1]-it2->sz[1],it1->sz[2]-it2->sz[2]); 101 } 102 inline ll calc(int u,int l,int r){ 103 ll res=0; 104 for(int p=u;p;p=fa[p]){ 105 node a=query(p,l,r); 106 res+=a.sz[1]; 107 if(p!=u) res+=a.sz[0]*dis(p,u); 108 if(fa[p]) res-=a.sz[2]+a.sz[0]*dis(fa[p],u); 109 } 110 return res; 111 } 112 int main(){ 113 ll ans=0; 114 n=read(),q=read(),maxn=read(); 115 bin[0]=1,logn[0]=-1; 116 for(int i=1;i<=20;++i) bin[i]=bin[i-1]<<1; 117 while(bin[tp+1]<=(n<<1)) ++tp; 118 for(int i=1;i<=(n<<1);++i) logn[i]=logn[i>>1]+1; 119 for(int i=1;i<=n;++i) val[i]=read(); 120 for(int i=1;i<n;++i){ 121 int u=read(),v=read(),e=read(); 122 add(u,v,e); 123 } 124 dfs1(1,0),ST(); 125 rt=0,son[0]=n+1,size=n,dfs2(1,0); 126 dfs4(rt); 127 while(q--){ 128 int a=read(),b=read(),c=read(); 129 b=(b+ans)%maxn,c=(c+ans)%maxn; 130 if(b>c) b^=c^=b^=c; 131 print(ans=calc(a,b,c)); 132 } 133 Ot(); 134 return 0; 135 }
转载于:https://www.cnblogs.com/bztMinamoto/p/9480501.html
BZOJ4012 [HNOI2015]开店 (动态点分治)相关推荐
- BZOJ 4012: [HNOI2015]开店 -- 动态树分治
4012: [HNOI2015]开店 Time Limit: 70 Sec Memory Limit: 512 MB Submit: 1463 Solved: 635 [Submit][Statu ...
- BZOJ4012 [HNOI2015]开店
BZOJ4012 [HNOI2015]开店 这道题因为太多人拿这个题卡$BZOJ$,于是成了权限题... 本蒟蒻表示没钱氪金... 无奈,拿出了洛谷:P3241 [HNOI2015]开店 还有$LOJ ...
- BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...
- bzoj4012开店 动态点分治
4012: [HNOI2015]开店 Time Limit: 70 Sec Memory Limit: 512 MB Submit: 1850 Solved: 801 [Submit][Statu ...
- 【HNOI 2015 开店】【动态点分治 + 前缀和】
题意:给出一个 n个点的树,每条边有长度,每个点有点权.有 q 个询问,每个询问查询点 u 到所有权值在 [l, r] 中的点的距离之和. 强制在线. 和幻想乡战略游戏差不多. 精髓在前缀和的应用上. ...
- 点分治动态点分治小结
(写篇博客证明自己还活着×2) 转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/8006488.html 有的时候,我们会发现这样一类题:它长得很像一个$O(n) ...
- [HNOI2015]开店
[HNOI2015]开店 法一 一个点到所有点距离? 树上路径问题,从一个点出发的 虽然不是统计一次,虽然强制在线,点分治也可以做! 因为可以动态点分治的分治树来搞! vector维护到根路径dis, ...
- 洛谷 P3241 [HNOI2015]开店 解题报告
P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...
- bzoj 4012: [HNOI2015]开店 主席树
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
最新文章
- 【NOIP校内模拟】T2 华莱士(环套树)
- [leetcode] 367. Valid Perfect Square
- k8s问题 CrashLoopBackOff
- 前端“黑话”polyfill
- python requests是什么_如何基于Python + requests实现发送HTTP请求
- 关于element框架的el-image点击后,页面出现卡死等情况的解决方式
- 帝国cms linux伪静态规则,帝国cms7.2伪静态规则怎么写
- c++ stl 容器 迭代器 stl用法示例
- 美国人与欧洲人为什么都吃转基因食品?
- useradd和adduser的区别
- 浪潮n系列服务器指示灯_中国服务器市场,浪潮跑出,联想和华为出现衰退
- Behavior Creator 行为树可视化编辑器
- 天才黑客,阿里安全科学家吴翰清:做对事只能赢一场,跟对人可以赢一生!...
- 微信支付开发(1)--普通商户申请、账户验证、签约、公众号授权流程详解
- 深入浅出MySQL规范
- 下载英文电子书网站,推荐
- Selenium WebDriver 常用API
- 强烈推荐:20款优秀的数据可视化工具
- 数据仓库,数据集市,数据湖
- 超外差,固定码,破解
热门文章
- Java转换成汇编asm程序
- QQ 为什么不能有 Linux 客户端
- 手把手教你用springboot配置多数据源
- 推荐:简单易用的iPhone iPad苹果设备管理工具itools
- Qt/C++编写物联网管理平台41-自动清理早期数据
- ajax传图片以及后台接收,前端ajax上传文件,图片,后端nodejs接收文件;
- 川大计算机非全日制专业课,2018年四川大学在职研究生非全日制考试科目有什么?...
- go操作excel方便么_Golang读写Excel的方法教程
- 为绿色而生:智慧矿山可视化数治监管
- 图片文字切割垂直投影算法