[HNOI2015]开店

法一

一个点到所有点距离?

树上路径问题,从一个点出发的

虽然不是统计一次,虽然强制在线,点分治也可以做!

因为可以动态点分治的分治树来搞!

vector维护到根路径dis,按age sort之后,处理后缀和

再维护到分治树father的贡献

O(nlog^2n)

代码:

#pragma GCC optimize("O2,Ofast,inline,unroll-all-loops,-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,popcnt")
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}namespace Miracle{
const int N=150000+5;
const int inf=0x3f3f3f3f;
int n,q,A;
int age[N];
struct node{int nxt,to,val;
}e[2*N];
int hd[N],cnt;
void add(int x,int y,int z){e[++cnt].nxt=hd[x];e[cnt].to=y;e[cnt].val=z;hd[x]=cnt;
}
int sz[N],nowsz;
struct po{int id,dis;ll bac;po(){}po(int dd,int ds){id=dd;dis=ds;bac=ds;}bool friend operator <(po a,po b){if(a.id!=b.id) return a.id<b.id;return a.dis<b.dis;}void op(){cout<<" id "<<id<<" dis "<<dis<<" bac "<<bac<<endl;}
};
vector<po>mem[N];
int dis[N][19];
int fa[N];
vector<po>df[N];
int rt;//,sz[N];
int vis[N];
int dep[N];
void fin(int x,int fa){sz[x]=1;int mxsz=0;for(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;if(y==fa||vis[y]) continue;fin(y,x);sz[x]+=sz[y];mxsz=max(mxsz,sz[y]);}mxsz=max(mxsz,nowsz-sz[x]);if(mxsz<=nowsz/2){rt=x;}
}
void dfs2(int x,int fa,int d){sz[x]=1;if(d!=1) df[rt].push_back(po(age[x],dis[x][d-1]));mem[rt].push_back(po(age[x],dis[x][d]));for(reg i=hd[x];i;i=e[i].nxt){int y=e[i].to;if(y==fa||vis[y]) continue;dis[y][d]=dis[x][d]+e[i].val;dfs2(y,x,d);sz[x]+=sz[y];}
}
void divi(int x,int d,int f){
//    cout<<" divi "<<x<<" d "<<d<<" f "<<f<<" nowsz "<<nowsz<<endl;rt=0;fin(x,0);
//    cout<<" rt "<<rt<<endl;dep[rt]=d;fa[rt]=f;dfs2(rt,0,d);if(d!=1){sort(df[rt].begin(),df[rt].end());for(reg i=df[rt].size()-2;i>=0;--i){df[rt][i].bac=df[rt][i+1].bac+df[rt][i].dis;}}sort(mem[rt].begin(),mem[rt].end());for(reg i=mem[rt].size()-2;i>=0;--i){mem[rt][i].bac=mem[rt][i+1].bac+mem[rt][i].dis;}vis[rt]=1;int tmp=rt;for(reg i=hd[tmp];i;i=e[i].nxt){int y=e[i].to;if(!vis[y]){nowsz=sz[y];divi(y,d+1,tmp);}}
}
ll wrk(int x,int L,int R){ll ret=0;int le=lower_bound(mem[x].begin(),mem[x].end(),po(L,-1))-mem[x].begin();int ri=upper_bound(mem[x].begin(),mem[x].end(),po(R,inf))-mem[x].begin();if(le!=mem[x].size()) ret+=mem[x][le].bac;if(ri!=mem[x].size()) ret-=mem[x][ri].bac;
//    cout<<"start "<<ret<<endl;int st=x;while(fa[x]){int y=fa[x];
//        cout<<" yy "<<y<<" dis "<<dis[st][dep[y]]<<endl;
//        for(reg i=0;i<mem[y].size();++i){
//            cout<<" i "<<i+1;mem[y][i].op();cout<<endl;
//        }int le=lower_bound(mem[y].begin(),mem[y].end(),po(L,-1))-mem[y].begin();int ri=upper_bound(mem[y].begin(),mem[y].end(),po(R,inf))-mem[y].begin();
//        cout<<" le ri "<<le<<" "<<ri<<endl;if(le!=mem[y].size()) ret+=mem[y][le].bac,ret+=(ll)(mem[y].size()-le)*dis[st][dep[y]];if(ri!=mem[y].size()) ret-=mem[y][ri].bac,ret-=(ll)(mem[y].size()-ri)*dis[st][dep[y]];
//        cout<<" ret before dele "<<ret<<endl;le=lower_bound(df[x].begin(),df[x].end(),po(L,-1))-df[x].begin();ri=upper_bound(df[x].begin(),df[x].end(),po(R,inf))-df[x].begin();if(le!=df[x].size()) ret-=df[x][le].bac,ret-=(ll)(df[x].size()-le)*dis[st][dep[y]];if(ri!=df[x].size()) ret+=df[x][ri].bac,ret+=(ll)(df[x].size()-ri)*dis[st][dep[y]];        x=fa[x];}return ret;
}
int main(){rd(n);rd(q);rd(A);for(reg i=1;i<=n;++i) rd(age[i]);int x,y,z;for(reg i=1;i<n;++i){rd(x);rd(y);rd(z);add(x,y,z);add(y,x,z);}nowsz=n;divi(1,1,0);ll ans=0;int a,b,L,R;while(q--){rd(x);rd(a);rd(b);L=min((a+ans)%A,(b+ans)%A),R=max((a+ans)%A,(b+ans)%A);
//        cout<<" true "<<x<<" "<<L<<" "<<R<<endl;printf("%lld\n",ans=wrk(x,L,R));}return 0;
}}
signed main(){Miracle::main();return 0;
}/*Author: *Miracle*Date: 2019/3/23 19:57:03
*/

View Code

法二:

两个点距离怎么算?

距离差分?

考虑距离是怎么算的,∑dis+n*dis(x)-2*dis(lca)

前面两个好算

考虑每个点贡献作为lca应有的贡献,也就是经过的sz

暴力跳不行,考虑树剖!

考虑x头上的边贡献

无[L,R]限制,直接把每个点到根的链上的sz++,

有[L,R],主席树rt按照age,主席树的叶子下标是dfn序,权值是[1,i]颜色的fdfn[p]的子树的个数和

加入一个点,重链跳,主席树标记永久化区间加

查询时候,找一段链作为lca的贡献,就是主席树差分查区间和

注意减去u子树的贡献

一个点有时候携带多个信息

一个区间的点的信息查询可以用主席树

树链的点的信息查询,树剖+主席树!

转载于:https://www.cnblogs.com/Miracevin/p/10585755.html

[HNOI2015]开店相关推荐

  1. BZOJ4012 [HNOI2015]开店

    BZOJ4012 [HNOI2015]开店 这道题因为太多人拿这个题卡$BZOJ$,于是成了权限题... 本蒟蒻表示没钱氪金... 无奈,拿出了洛谷:P3241 [HNOI2015]开店 还有$LOJ ...

  2. 洛谷 P3241 [HNOI2015]开店 解题报告

    P3241 [HNOI2015]开店 题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想法当然非 ...

  3. BZOJ 4012: [HNOI2015]开店 -- 动态树分治

    4012: [HNOI2015]开店 Time Limit: 70 Sec  Memory Limit: 512 MB Submit: 1463  Solved: 635 [Submit][Statu ...

  4. 4012: [HNOI2015]开店

    4012: [HNOI2015]开店 Time Limit: 70 Sec  Memory Limit: 512 MB Submit: 1241  Solved: 536 [Submit][Statu ...

  5. bzoj 4012: [HNOI2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  6. bzoj 4012: [HNOI2015]开店 主席树

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  7. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

  8. BZOJ4012 [HNOI2015]开店 (动态点分治)

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  9. luogu P3241 [HNOI2015]开店

    传送门 (下面记年龄为\(a_x\))题目要求的是\[\sum_{x=1}^{n} [a_x\in [l,r]]*dis(x,u)=\sum_{x=1}^{n} [a_x\in [l,r]]*de_x ...

最新文章

  1. 数组做参数_ES6 系列:你不知道的 Rest 参数与 Spread 语法细节
  2. delphi中try的用法1
  3. 归档—监控ORACLE数据库告警日志
  4. android预加载布局,Android 懒加载优化
  5. Java+MyEclipse+Tomcat (三)配置MySQL及查询数据显示在JSP网页中
  6. 排列出所有子串暴力递归
  7. CPU+GPU异构计算完全解析
  8. python 编码 解码 读写文件
  9. 期刊缩写查询_干活分享——SCI期刊名英文缩写查询
  10. x86-64寄存器与栈帧(转载)
  11. 吝啬的国度 ---用vector 来构图
  12. java jms消息队列_JMS消息队列ActiveMQ(发布/订阅模式)
  13. php底部导航栏,微信小程序之底部导航栏目开发(附代码)
  14. 人事面试100问题--巧妙应答
  15. 防盗报警器c语言程序,基于单片机的汽车防盗报警系统的设计毕业论文.doc
  16. 迈克菲实验室:2018五大网络安全威胁
  17. 华为服务器故障灯不开机_华为手机开不了机指示灯亮,怎么办
  18. leetcode---栈
  19. Linux 内核配置项详解 myimx6
  20. 基础工具类Joiner的使用

热门文章

  1. [转载] Python(析构函数)
  2. css part 2
  3. Identity Server 4 原理和实战(完结)_----选看 OAuth 2.0 简介(上)
  4. 下载EPM包详细运行日志
  5. 简单解决 WIN10更新后 远程桌面提示 CredSSP加密Oracle修正的问题
  6. 有关UITableviewCell 重用内存 内部解析
  7. 第四章 jQuery文档处理
  8. HDU 1027 全排列
  9. pytorch---之pin_memory
  10. Linux搭建NFS文件服务器