博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树链剖分(模板)
阅读量:4634 次
发布时间:2019-06-09

本文共 2860 字,大约阅读时间需要 9 分钟。

题目链接:https://www.luogu.org/problemnew/show/P3384

题意:树链剖分模板题,但是比较坑的是要注意取模,每个可能炸int的地方都要加取模。

代码如下:

#include
#include
using namespace std;const int maxn=100005;//链式向前星int cnt1,head[maxn],w[maxn],wt[maxn];int n,m,r,Mod,res;int son[maxn],id[maxn],fa[maxn],cnt2,dep[maxn],siz[maxn],top[maxn];struct node1{ int v,nex;}edge[maxn<<1];void adde(int u,int v){ edge[++cnt1].v=v; edge[cnt1].nex=head[u]; head[u]=cnt1;}//线段树部分struct node2{ int l,r,val,add;}tr[maxn<<2];void build(int v,int l,int r){ tr[v].l=l,tr[v].r=r; if(l==r){ tr[v].val=wt[r]%Mod; return; } int mid=(l+r)>>1; build(v<<1,l,mid); build(v<<1|1,mid+1,r); tr[v].val=(tr[v<<1].val+tr[v<<1|1].val+Mod)%Mod;}void pushdown(int v){ tr[v<<1].val+=tr[v].add*(tr[v<<1].r-tr[v<<1].l+1); tr[v<<1|1].val+=tr[v].add*(tr[v<<1|1].r-tr[v<<1|1].l+1); tr[v<<1].val%=Mod; tr[v<<1|1].val%=Mod; tr[v<<1].add+=tr[v].add; tr[v<<1|1].add+=tr[v].add; tr[v].add=0;}void update(int v,int l,int r,int k){ if(l<=tr[v].l&&r>=tr[v].r){ tr[v].val+=k*(tr[v].r-tr[v].l+1); tr[v].val%=Mod; tr[v].add+=k; return; } if(tr[v].add) pushdown(v); int mid=(tr[v].l+tr[v].r)>>1; if(l<=mid) update(v<<1,l,r,k); if(r>mid) update(v<<1|1,l,r,k); tr[v].val=(tr[v<<1].val+tr[v<<1|1].val+Mod)%Mod;}void query(int v,int l,int r){ if(l<=tr[v].l&&r>=tr[v].r){ res+=tr[v].val; res%=Mod; return; } if(tr[v].add) pushdown(v); int mid=(tr[v].l+tr[v].r)>>1; if(l<=mid) query(v<<1,l,r); if(r>mid) query(v<<1|1,l,r); tr[v].val=(tr[v<<1].val+tr[v<<1|1].val+Mod)%Mod;}int qRange(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]
dep[y]) swap(x,y); res=0; query(1,id[x],id[y]); ans=(ans+res)%Mod; return ans;}void updRange(int x,int y,int k){ k%=Mod; while(top[x]!=top[y]){ if(dep[top[x]]
dep[y]) swap(x,y); update(1,id[x],id[y],k);}int qSon(int x){ res=0; query(1,id[x],id[x]+siz[x]-1); return res;}void updSon(int x,int k){ update(1,id[x],id[x]+siz[x]-1,k);}void dfs1(int x,int f,int deep){ dep[x]=deep; fa[x]=f; siz[x]=1; int maxson=-1; for(int i=head[x];i;i=edge[i].nex){ int y=edge[i].v; if(y==f) continue; dfs1(y,x,deep+1); siz[x]+=siz[y]; if(siz[y]>maxson) son[x]=y,maxson=siz[y]; }}void dfs2(int x,int tp){ id[x]=++cnt2; wt[cnt2]=w[x]; top[x]=tp; if(!son[x]) return; dfs2(son[x],tp); for(int i=head[x];i;i=edge[i].nex){ int y=edge[i].v; if(y==fa[x]||y==son[x]) continue; dfs2(y,y); }}int main(){ scanf("%d%d%d%d",&n,&m,&r,&Mod); for(int i=1;i<=n;++i) scanf("%d",&w[i]); for(int i=0;i

 

转载于:https://www.cnblogs.com/FrankChen831X/p/11181530.html

你可能感兴趣的文章
ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
查看>>
#include<bits/stdc++.h>包含C++的所有头文件
查看>>
Vue插槽 slot
查看>>
HDOJ1004
查看>>
Eclipse中部分快捷键
查看>>
LintCode: Unique Characters
查看>>
从一个OutOfMemoryError 学会了分析Java内存泄漏问题
查看>>
过滤器与拦截器区别
查看>>
USACO 1.5.4 Checker Challenge
查看>>
第二阶段站立会议7
查看>>
[18]Debian Linux Install GNU GCC Compiler and Development Environment
查看>>
12种排序算法
查看>>
HDU - 5934
查看>>
JAVA多线程
查看>>
ACE(Adaptive Communication Environment)介绍
查看>>
delphi 更改DBGrid 颜色技巧
查看>>
python编码问题
查看>>
POJ 2031 Building a Space Station
查看>>
面向对象1
查看>>
编程开发之--java多线程学习总结(5)
查看>>