题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012

题意概述:给出一颗N点的树,保证树上所有点的度不超过3,树上每个点有权值,每条边有权值,现在有Q组询问,每组给出信息u,L,R,问点权在区间[L,R]的点到点u的距离和为多少。强制在线。

N<=150000,Q<=200000.

可能这是我这几天做过的题里面最水但是最码的一个了。。。。

实际上看见树上所有点的度不超过3就感觉可以用边分治做,具体的思路实际上很简单,建立一个边分治结构,这个结构大约有logN层,每层有N个点,对于每组询问,看询问的点u在当前树被分成的两棵子树中的哪一棵,统计出另一个子树中所有点权在询问区间内的点到u的距离,然后递归到u所在的子树,最终就可以计算出答案。

重点在于实现,一不小心处理的时候就会多写出几个常数出来。。。(不要问我是怎么知道的)

实际上这个题我yy的东西重点就在于把边分治建立成一个二叉树的结构然后在里面去搞事情(小火车万岁!),最多有2N个分治结构(每条边会产生2个,有N-1条边)。每一层每个点只会有一个信息,利用这个性质可以记录很多东西,询问的时候在分治结构中递归,令当前分治结构中询问点所在的子树根节点为x,另一边的子树根节点为y(实际上就是断掉的边的两个端点),每一次询问的时候就在y的信息里面二分计算询问区间内点到y的距离,同时得到这些点的数量,然后把从y经过x到u的距离补全累加到答案中,递归。(要点已经交代完了,剩下的请各位自己yy,手动滑稽)

预处理可以用归并排序做到O(nlogn),主要复杂度在查询,单次是O(log2n)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=;
const int maxd=;
typedef long long LL; int N,Q,A,L,R,age[maxn]; LL ans,dist[maxd][maxn],sum[maxd][maxn];
struct edge{ int to,next,w; }E[maxn<<];
int first[maxn],np,sz[maxn],rt[maxd][maxn];
int ID[maxd][maxn],cnt;
int ke[maxn<<],MAX,ch[maxn<<][],l[maxn<<],r[maxn<<],size[maxd],tot[maxn<<];
bool vis[maxn<<]; void _scanf(int &x)
{
x=;
char cha=getchar();
while(cha<''||cha>'') cha=getchar();
while(cha>=''&&cha<='') x=x*+cha-'',cha=getchar();
}
int out_cnt,out[];
void _printf(LL x)
{
out_cnt=;
out[++out_cnt]=x%,x/=;
while(x) out[++out_cnt]=x%,x/=;
while(out_cnt) putchar(''+out[out_cnt--]);
}
void add_edge(int u,int v,int w)
{
E[++np]=(edge){v,first[u],w};
first[u]=np;
}
void data_in()
{
_scanf(N);_scanf(Q);_scanf(A);
for(int i=;i<=N;i++) _scanf(age[i]);
int x,y,z;
for(int i=;i<N;i++){
_scanf(x);_scanf(y);_scanf(z);
add_edge(x,y,z);
add_edge(y,x,z);
}
}
void DFS(int i,int f,int SZ,int id,int d,LL l)
{
sz[i]=,size[d]++,dist[d][i]=l;
for(int p=first[i];p;p=E[p].next){
int j=E[p].to;
if(j==f||vis[p]) continue;
rt[d][j]=rt[d][i];
DFS(j,i,SZ,id,d,l+E[p].w);
sz[i]+=sz[j];
int tmp=max(sz[j],SZ-sz[j]);
if(tmp<MAX) MAX=tmp,ke[id]=p;
}
}
void merge_sort(int x,int d)
{
int pos=l[x],i=l[ch[x][]],j=r[ch[x][]],r1=r[ch[x][]],r2=r[ch[x][]];
while(i<r1&&j<r2) ID[d][pos++]=age[ID[d+][i]]<age[ID[d+][j]]?ID[d+][i++]:ID[d+][j++];
while(i<r1) ID[d][pos++]=ID[d+][i++];
while(j<r2) ID[d][pos++]=ID[d+][j++];
}
void div_tree(int i,int SZ,int id,int d)
{
MAX=SZ;
l[id]=size[d],rt[d][i]=i;
DFS(i,,SZ,id,d,);
r[id]=size[d];
if((tot[id]=SZ)==){ ID[d][l[id]]=i; return; }
int o0=E[ke[id]].to,o1=E[(ke[id]-^)+].to;
int _sz0=sz[o0],_sz1=SZ-sz[o0];
vis[ke[id]]=vis[(ke[id]-^)+]=;
div_tree(o0,_sz0,ch[id][]=++cnt,d+);
div_tree(o1,_sz1,ch[id][]=++cnt,d+);
merge_sort(id,d);
sum[d][l[id]]=dist[d][ID[d][l[id]]];
for(int j=l[id]+;j<r[id];j++) sum[d][j]=sum[d][j-]+dist[d][ID[d][j]];
}
bool cmp(int x,int y){ return age[x]<age[y]; }
void solve(int p,int id,int d)
{
if(tot[id]==) return;
int x=E[ke[id]].to,y=E[(ke[id]-^)+].to;
int dd=rt[d][p]!=x,t=ch[id][dd^];
age[]=L;
int ll=lower_bound(ID[d]+l[t],ID[d]+r[t],,cmp)-ID[d]-;
LL v1=ll>=l[t]?sum[d][ll]:;
age[]=R;
int rr=upper_bound(ID[d]+l[t],ID[d]+r[t],,cmp)-ID[d]-;
LL v2=rr>=l[t]?sum[d][rr]:;
ans+=v2-v1+(rr-ll)*(E[ke[id]].w+dist[d][p]);
solve(p,ch[id][dd],d+);
}
void work()
{
div_tree(,N,++cnt,);
int u,a,b;
for(int i=;i<=Q;i++){
_scanf(u);_scanf(a);_scanf(b);
L=min((a+ans)%A,(b+ans)%A);
R=max((a+ans)%A,(b+ans)%A);
ans=;
solve(u,,);
_printf(ans),putchar('\n');
}
}
int main()
{
data_in();
work();
return ;
}

BZOJ 4012 HNOI2015 开店 树的边分治+分治树的更多相关文章

  1. BZOJ 4012 [HNOI2015]开店 (区间修改 永久化标记 主席树)

    讲得好啊 主席树区间修改了,每一次遇到整区间就打永久化标记(不下传,访问的时候沿路径上的标记算答案)然后returnreturnreturn,那么每修改一次只会访问到lognlognlogn个节点,再 ...

  2. BZOJ 4012 [HNOI2015]开店 (树分治+二分)

    题目大意: 给你一棵树,边有边权,点有点权,有很多次询问,求点权$\in[l,r]$的所有节点到某点$x$的距离之和,强制在线 感觉这个题应该放在动态点分之前做= = 套路方法和动态点分是一样的 每次 ...

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

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

  4. bzoj 4012: [HNOI2015]开店

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

  5. 【BZOJ】4012: [HNOI2015]开店

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 给出一个$n$个点的树,树上每一个点都有一个值$age$,每条边都有边权,每次查询一 ...

  6. [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)

    4012: [HNOI2015]开店 Time Limit: 70 Sec  Memory Limit: 512 MBSubmit: 2168  Solved: 947[Submit][Status] ...

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

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

  8. 【BZOJ4012】[HNOI2015]开店 动态树分治+二分

    [BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...

  9. [HNOI2015]开店 树链剖分,主席树

    [HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...

随机推荐

  1. mysql的子查询in()操作及按指定顺序显示

    代码示例: in(逗号分隔开的值列表) 释:是否存在于值列表中 --------------------- 示例: select * from test where id in(3,1,5) orde ...

  2. linux下通过源码安装git

    1.移除旧版本git [root@Git ~]# git --version ## 查看自带的版本git version 1.8.3.1 [root@Git ~]# yum remove git ## ...

  3. Struts2 第一讲 -- Struts2开发前奏

    我们在学习Struts之前,先来复习一下Servlet,众所周知Servlet是JavaWeb的三大组件.我们发送一个请求,这个请求交给Servlet处理,Servlet将处理的结果返还给浏览器.每个 ...

  4. Unity 游戏框架搭建 (八) 减少加班利器-QLog

    为毛要实现这个工具? 在我小时候,每当游戏到了测试阶段,交给QA测试,QA测试了一会儿拿着设备过来说游戏闪退了....当我拿到设备后测了好久Bug也没有复现,排查了好久也没有头绪,就算接了Bugly拿 ...

  5. jquery mobile 移动web(2)

    button 按钮 data-role="button" 将超链接变成button. 具有icon 图标的button 组件. 提供了18常用的图标 data-icon =&quo ...

  6. bootstrap模态框传值操作

    1.bootstrap模态框之html代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"& ...

  7. ASP.NET HttpHandler加水印

    一.指定Handler方式 1.添加Handler一般处理程序 2.PicHandler.ashx源码如下: 需要的引用: using System; using System.Collections ...

  8. ajax在同一页面中同控制器不同方法中调用数据并异步刷新的实例

    我在实习以来都有做一些笔记,之前做的笔记都在简书里,现在我提前把公司给我的任务做好了,坐在电脑前又不好玩别的,那么我就整理下我之前的笔记吧!(此项目是thinkphp5开发的) 先上效果图 这是整体页 ...

  9. http状态码(status_codes)

    首先:1XX 接受的请求正在处理,2XX请求正常处理完毕,3XX需要进行附加操作以完成请求(重定向?),4XX服务器无法处理请求(也就是客户端请求错误),5XX服务器处理请求出错. 当然不仅仅是一张图 ...

  10. Redis缓存数据库的安装与配置(2)

    1.为php安装redis客户端扩展 wget https://github.com/nicolasff/phpredis/archive/master.zip tar xf phpredis-mas ...