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
写完莫名其妙地过了样例,交上去莫名其妙地WA了一发后改了改范围然后莫名其妙地A了。
考虑用动态树分治来做。对于以x为分治根的所有节点,记录它子树中所有点到它本身的颜色和距离,以及它子树中所有点到它分治父亲的颜色和距离。sort一下预处理前缀和,就可以在上面二分了,为了省事加了个虚拟节点颜色为-1。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
char ch=getchar();int x=,f=;
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
const int maxn=;
typedef long long LL;
int n,q,first[maxn],next[maxn],to[maxn],dis[maxn],e;
void AddEdge(int w,int v,int u) {
to[++e]=v;dis[e]=w;next[e]=first[u];first[u]=e;
to[++e]=u;dis[e]=w;next[e]=first[v];first[v]=e;
}
int mn[maxn][],dep[maxn],pos[maxn],cnt;
void dfs(int x,int fa) {
mn[++cnt][]=dep[x];pos[x]=cnt;
ren if(to[i]!=fa) {
dep[to[i]]=dep[x]+dis[i];
dfs(to[i],x);
mn[++cnt][]=dep[x];
}
}
int Log[maxn];
void init() {
Log[]=-;rep(,cnt) Log[i]=Log[i>>]+;
for(int j=;(<<j)<=cnt;j++)
for(int i=;i+(<<j)-<=cnt;i++)
mn[i][j]=min(mn[i][j-],mn[i+(<<j-)][j-]);
}
LL dist(int x,int y) {
LL ans=dep[x]+dep[y];x=pos[x];y=pos[y];if(x>y) swap(x,y);
int k=Log[y-x+];
return ans-2LL*min(mn[x][k],mn[y-(<<k)+][k]);
}
int age[maxn],vis[maxn],f[maxn],s[maxn],size,root;
void getroot(int x,int fa) {
s[x]=;int maxs=;
ren if(!vis[to[i]]&&to[i]!=fa) getroot(to[i],x),s[x]+=s[to[i]],maxs=max(maxs,s[to[i]]);
f[x]=max(maxs,size-s[x]);
if(f[root]>f[x]) root=x;
}
struct Arr {
int c;LL val;
bool operator < (const Arr& ths) const {return c<ths.c;}
Arr operator - (const Arr& ths) const {Arr t;t.val=val-ths.val;t.c=c-ths.c;return t;}
}A[maxn*];
int cur,L1[maxn],R1[maxn],L2[maxn],R2[maxn];
void dfs(int x,int fa,int dep) {
A[++cur]=(Arr){age[x],dep};s[x]=;
ren if(to[i]!=fa&&!vis[to[i]]) dfs(to[i],x,dep+dis[i]),s[x]+=s[to[i]];
}
int fa[maxn];
void solve(int x,int F) {
vis[x]=;fa[x]=F;
A[++cur]=(Arr){-,};L1[x]=cur;dfs(x,,);R1[x]=cur;
sort(A+L1[x],A+R1[x]+);
rep(L1[x]+,R1[x]) A[i].val+=A[i-].val;
ren if(!vis[to[i]]) {
size=f[]=s[to[i]];getroot(to[i],root=);
A[++cur]=(Arr){-,};L2[root]=cur;dfs(to[i],,dis[i]);R2[root]=cur;
sort(A+L2[root],A+R2[root]+);
rep(L2[root]+,R2[root]) A[i].val+=A[i-].val;
solve(root,x);
}
}
LL lastans,T;
Arr get(int x,int ql,int qr,int L,int R) {
Arr t;
t.c=qr;
int pos1=upper_bound(A+L,A+R+,t)-A-;
t.c=ql-;
int pos2=upper_bound(A+L,A+R+,t)-A-;
t.c=pos1-pos2;t.val=A[pos1].val-A[pos2].val;
return t;
}
LL query(int x,int l,int r) {
LL ret=get(x,l,r,L1[x],R1[x]).val;
for(int i=x;fa[i];i=fa[i]) {
Arr t=get(fa[i],l,r,L1[fa[i]],R1[fa[i]])-get(i,l,r,L2[i],R2[i]);
ret+=t.val+t.c*dist(fa[i],x);
}
return ret;
}
int main() {
n=read();q=read();T=read();
rep(,n) age[i]=read();
rep(,n) AddEdge(read(),read(),read());
dfs(,);init();
size=f[]=n;getroot(,root=);
int t=root;solve(root,);root=t;
while(q--) {
int u=read(),a=(read()+lastans)%T,b=(read()+lastans)%T;
if(a>b) swap(a,b);
printf("%lld\n",lastans=query(u,a,b));
}
return ;
}
BZOJ4012 [HNOI2015]开店的更多相关文章
- [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)
4012: [HNOI2015]开店 Time Limit: 70 Sec Memory Limit: 512 MBSubmit: 2168 Solved: 947[Submit][Status] ...
- BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...
- BZOJ4012 HNOI2015开店(树链剖分+主席树)
考虑这样一个问题:一棵树初始全是白点,有两种操作:把一个点染黑:询问某点到所有黑点的距离之和. 注意到树上两点x和y的距离为depth[x]+depth[y]-depth[lca(x,y)]*2.要求 ...
- BZOJ4012: [HNOI2015]开店【动态点分治】
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- BZOJ4012 [HNOI2015]开店 (动态点分治)
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】
题目链接 BZOJ4012 题解 Mychael并没有A掉,而是T掉了 讲讲主要思路 在点分树上每个点开两棵\(splay\), 平衡树\(A\)维护子树中各年龄到根的距离 平衡树\(B\)维护子树中 ...
- 【BZOJ4012】[HNOI2015]开店 动态树分治+二分
[BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...
- 【BZOJ4012】开店(主席树)
[BZOJ4012]开店(主席树) 题面 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱 ...
- [HNOI2015]开店 树链剖分,主席树
[HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...
随机推荐
- BZOJ 1004
一道奇怪的数学题.为了这道题我看了很多题解,到底还是一知半解..整个感觉就是上了一场数学课. HNOI2008 Cards 题目描述 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有 ...
- apache ab压力测试报错(apr_socket_recv: Connection reset by peer (104))
apache ab压力测试报错(apr_socket_recv: Connection reset by peer (104)) 今天用apache 自带的ab工具测试,当并发量达到1000多的时 ...
- mac os x查看端口命令
`netstat` 命令 a. `netstat -nat | grep <端口号>` 转自: http://my.oschina.net/foreverich/blog/402252
- ios7技巧:你需要掌握的19个iOS7使用技巧
从右往左滑动屏幕,可看到信息收到的时间. 指南针应用还可以用作水平仪,滑动屏幕即可. 被苹果称作Spotlight的搜索功能有所改变.在屏幕中间向下滑动即可打开该项功能,你可以搜索文本.邮件.应用.歌 ...
- 【Python】python list 迭代删除
最好方式使用filter,代码示例: def _filter(self, item): ): return False return True #lambda e:e%!= data['items'] ...
- css选择器集体声明
<title>静夜思</title><style type="text/css">h1,#two,.red{ color:#ff0000; fo ...
- python操作Excel读写--使用xlrd
一.安装xlrd模块 到python官网下载http://pypi.python.org/pypi/xlrd模块安装,前提是已经安装了python 环境. 二.使用介绍 1.导入模块 import x ...
- ecshop设置一个子类对应多个父类并指定跳转url的修改方法
这是一篇记录在日记里面的技术文档,其实是对ecshop的二次开发.主要作用是将一个子类对应多个父类,并指定条跳转url的功能.ecshop是一款在线购物网站,感兴趣的可以下载源码看看.我们看看具体是怎 ...
- SGU 106 The equation
H - The equation Time Limit:250MS Memory Limit:4096KB 64bit IO Format:%I64d & %I64u Subm ...
- CUDA学习笔记(三)——CUDA内存
转自:http://blog.sina.com.cn/s/blog_48b9e1f90100fm5f.html 结合lec07_intro_cuda.pptx学习 内存类型 CGMA: Compute ...