听说正解点分树?我不会就对了

此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和

不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower\_bound\) 一下找到区间 \([l,r]\)

在主席树上实现区间加,肯定要标记永久化。每次最多修改 \(2\lfloor \log^n\rfloor\) 个区间,所以一次最多会开出 \(4\lfloor \log^n\rfloor-1\) 个结点,空间复杂度理论上是 \(O(4n\log^2n)\),时间复杂度 \(O(n\log^2 n)\)

但是神奇的是,在 \(n\leq 150000\) 的时候,我空间只开了 \(100\) 倍就过了(雾

\(Code\ Below:\)

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define F first
#define S second
using namespace std;
const int maxn=150000+10;
const int inf=0x3f3f3f3f;
int n,q,A,val[maxn],head[maxn],tot;pii a[maxn];
int dep[maxn],top[maxn],siz[maxn],son[maxn],fa[maxn],id[maxn],tim;
int T[maxn],L[maxn*100],R[maxn*100],cnt;ll dis[maxn],sumE[maxn],sumdis[maxn],sum[maxn*100],lazy[maxn*100]; struct node{
int to,next,val;
}e[maxn<<1]; inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
} inline void addedge(int x,int y,int w){
e[++tot].to=y;
e[tot].val=w;
e[tot].next=head[x];
head[x]=tot;
} void dfs1(int x,int f){
siz[x]=1;fa[x]=f;
dep[x]=dep[f]+1;
int maxson=-1;
for(int i=head[x],y;i;i=e[i].next){
y=e[i].to;
if(y==f) continue;
val[y]=e[i].val;
dis[y]=dis[x]+e[i].val;
dfs1(y,x);
siz[x]+=siz[y];
if(siz[y]>maxson){
maxson=siz[y];
son[x]=y;
}
}
} void dfs2(int x,int topf){
id[x]=++tim;
sumE[tim]=val[x];
top[x]=topf;
if(son[x]) dfs2(son[x],topf);
for(int i=head[x],y;i;i=e[i].next){
y=e[i].to;
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
} void update(int &now,int pre,int Le,int Ri,int l,int r){
now=++cnt;L[now]=L[pre];R[now]=R[pre];lazy[now]=lazy[pre];
sum[now]=sum[pre]+(sumE[min(Ri,r)]-sumE[max(Le,l)-1]);
if(Le <= l && r <= Ri){
lazy[now]++;
return ;
}
int mid=(l+r)>>1;
if(Le <= mid) update(L[now],L[pre],Le,Ri,l,mid);
if(Ri > mid) update(R[now],R[pre],Le,Ri,mid+1,r);
} ll query(int u,int v,int Le,int Ri,int l,int r){
if(Le <= l && r <= Ri) return sum[v]-sum[u];
int mid=(l+r)>>1;ll ans=(lazy[v]-lazy[u])*(sumE[min(Ri,r)]-sumE[max(Le,l)-1]);
if(Le <= mid) ans+=query(L[u],L[v],Le,Ri,l,mid);
if(Ri > mid) ans+=query(R[u],R[v],Le,Ri,mid+1,r);
return ans;
} inline void modify(int i,int x){
T[i]=T[i-1];
while(top[x]!=1){
update(T[i],T[i],id[top[x]],id[x],1,n);
x=fa[top[x]];
}
update(T[i],T[i],1,id[x],1,n);
} inline ll ask(int u,int v,int x){
ll ans=0;
while(top[x]!=1){
ans+=query(T[u],T[v],id[top[x]],id[x],1,n);
x=fa[top[x]];
}
ans+=query(T[u],T[v],1,id[x],1,n);
return ans;
} int main()
{
n=read(),q=read(),A=read();
int x,y,w;
for(int i=1;i<=n;i++) a[i]=mp(read(),i);
for(int i=1;i<n;i++){
x=read(),y=read(),w=read();
addedge(x,y,w);addedge(y,x,w);
}
dfs1(1,0);dfs2(1,1);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) sumE[i]+=sumE[i-1],sumdis[i]=sumdis[i-1]+dis[a[i].S];
for(int i=1;i<=n;i++) modify(i,a[i].S);
int u,l,r;ll lastans=0;
while(q--){
u=read(),l=read(),r=read();
x=(l+lastans)%A;y=(r+lastans)%A;
if(x>y) swap(x,y);
l=lower_bound(a+1,a+n+1,mp(x,0))-a;
r=upper_bound(a+1,a+n+1,mp(y,inf))-a-1;
printf("%lld\n",lastans=dis[u]*(r-l+1)+(sumdis[r]-sumdis[l-1])-2*ask(l-1,r,u));
lastans%=A;
}
return 0;
}

[HNOI2015]开店(树剖+主席树+标记永久化)的更多相关文章

  1. BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树

    BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...

  2. 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...

  3. [SCOI2015]情报传递[树剖+主席树]

    [SCOI2015]情报传递 题意大概就是 使得在 \(i\) 时刻加入一个情报员帮您传情报 然后询问 \(x,y,c\) 指 \(x\)到\(y\)多少个人有风险-(大于c)的都有风险-每天风险值+ ...

  4. POJ3237 Tree(树剖+线段树+lazy标记)

    You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...

  5. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  6. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  7. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  8. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

  9. 洛谷P4315 月下“毛景树”(树剖+线段树)

    传送门 woc这该死的码农题…… 把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了 然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$ 然后是几个注意点 ...

随机推荐

  1. 【Linux】CentOS 7.4 安装 MySQL 8.0.12 解压版

    安装环境/工具 1.Linux(CentOS 7.4版) 2.mysql-8.0.12-el7-x86_64.tar.gz 安装步骤 参考:https://dev.mysql.com/doc/refm ...

  2. Mac OS X下安装Python的MySQLdb模块【终结版】

    1.下载源文件: https://pypi.org/project/MySQL-python/ 2.cd 到源文件所在目录: 3.在目录下使用 python setup.py install 命令安装 ...

  3. LD_LIBRARY_PATH

    LD_LIBRARY_PATH是Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径. 在linux下可以用export命令来设置这个值,比如 在linux ...

  4. 使用delphi-cross-socket 开发kbmmw smart http service

    前几天我说了使用delphi-cross-socket 扩展kbmmw 的跨平台支持,今天我说一下使用 kbmMWCrossScoketHttpServerTransport 在linux 下支持 k ...

  5. 安卓逆向学习---初始APK、Dalvik字节码以及Smali

    参考链接:https://www.52pojie.cn/thread-395689-1-1.html res目录下资源文件在编译时会自动生成索引文件(R.java ), asset目录下的资源文件无需 ...

  6. springboot深入学习(二)-----profile配置、运行原理、web开发

    一.profile配置 通常企业级应用都会区分开发环境.测试环境以及生产环境等等.spring提供了全局profile配置的方式,使得在不同环境下使用不同的applicaiton.properties ...

  7. 华为机试-iNOC产品部-杨辉三角的变形

    题目描述 1 1 1 1 1 2 3 2 1 1 3 6 7 6 3 11 4 10 16 19 16 10 4 1以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数,左上角数 ...

  8. 词袋模型(BOW, bag of words)

    词集模型:单词构成的集合,每个单词只出现一次. 词袋模型:把每一个单词都进行统计,同时计算每个单词出现的次数. 在train_x中,总共有6篇文档,每一行代表一个样本即一篇文档.我们的目标是将trai ...

  9. (转)PHP5使用cookie时报错 cannot modify header information - headers already sent by (......)

    转自:http://blog.csdn.net/buyingfei8888/article/details/8899797 运行有警告Warning: Cannot modify header inf ...

  10. [Selenium With C#基础教程] Lesson-01环境搭建

    作者:Surpassme 来源:http://www.jianshu.com/p/33b87bc00233 声明:本文为原创文章,如需转载请在文章页面明显位置给出原文链接,谢谢. 最近开始复习Sele ...