【模板】树链剖分/轻重链剖分
- vector
- tree
- arr
- map
test code:
点击查看代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline ll read(){
ll q=0;char ch=' ';
while(ch<'0' || ch>'9') ch=getchar();
while(ch<='9' && ch>='0') q=q*10+ch-'0',ch=getchar();
return q;
}
const int MAXN = 1e5+25;
ll n,m,s,p,arr[MAXN];
vector <int> G[MAXN];
ll dep[MAXN],fa[MAXN],siz[MAXN],son[MAXN];//dfs1: to dispose the point
ll cnt,id[MAXN],trr[MAXN],top[MAXN];//dfs2: to dispose the chain
struct Segment_Tree{//A segment tree to maintain the trr
#define mid ((l+r)>>1)
ll arr[MAXN],tre[MAXN<<2],tag[MAXN<<2];
inline void build(int l,int r,int p){
if(l==r){tre[p]=arr[l];return;}
build(l,mid,p*2);build(mid+1,r,p*2+1);
tre[p]=tre[p*2]+tre[p*2+1];return;
}
inline void push_down(int l,int r,int p){
if(tag[p]==0) return;
tre[p*2]+=tag[p]*(mid-l+1),tre[p*2+1]+=tag[p]*(r-mid);
tag[p*2]+=tag[p],tag[p*2+1]+=tag[p];tag[p]=0;
return;
}
inline void add(int l,int r,int p,int a,int b,int k){
if(a<=l && r<=b){tre[p]+=k*(r-l+1),tag[p]+=k;return;}
push_down(l,r,p);
if(a<=mid) add(l,mid,p*2,a,b,k);
if(b>mid) add(mid+1,r,p*2+1,a,b,k);
tre[p]=tre[p*2]+tre[p*2+1];return;
}
inline ll query(int l,int r,int p,int a,int b){
if(a<=l && r<=b){return tre[p];}
ll temp=0;push_down(l,r,p);
if(a<=mid) temp+=query(l,mid,p*2,a,b);
if(b>mid) temp+=query(mid+1,r,p*2+1,a,b);
return temp;
}
}tret;
void dfs1(int x,int f,int pdep){
dep[x]=pdep,fa[x]=f,siz[x]=1;
int wson=-1;
for(int i=0; i<G[x].size(); i++){
int v=G[x][i];
if(v==f) continue;
dfs1(v,x,pdep+1);siz[x]+=siz[v];
if(siz[v]>wson) wson=siz[v],son[x]=v;
}
return;
}
void dfs2(int x,int chf){
id[x]=++cnt,trr[cnt]=arr[x],top[x]=chf;
if(!son[x]){ return;}dfs2(son[x],chf);
for(int i=0; i<G[x].size(); i++){
int v=G[x][i];
if(v==fa[x] || v==son[x]) continue;
dfs2(v,v);
}
return;
}
void ch_add(ll a,ll b,ll k){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]]) swap(a,b);
tret.add(1,n,1,id[top[a]],id[a],k);
a=fa[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);
tret.add(1,n,1,id[a],id[b],k);
}
ll ch_query(ll a,ll b){
ll ans=0;
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]]) swap(a,b);
ans+=tret.query(1,n,1,id[top[a]],id[a]);
a=fa[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);
ans+=tret.query(1,n,1,id[a],id[b]);
return ans;
}
void tre_add(ll r,ll k){
tret.add(1,n,1,id[r],id[r]+siz[r]-1,k);
}
ll tre_query(ll r){
return tret.query(1,n,1,id[r],id[r]+siz[r]-1);
}
signed main(){
n=read(),m=read(),s=read(),p=read();
for(int i=1; i<=n; i++) arr[i]=read();
for(int i=1; i<=n-1; i++){
int u=read(),v=read();
G[u].push_back(v);G[v].push_back(u);
}
dfs1(s,s,1);
dfs2(s,s);
for(int i=1; i<=n; i++) tret.arr[i]=trr[i];
tret.build(1,n,1);
for(int i=1; i<=m; i++){
ll op=read();
if(op==1){
ll l=read(),r=read(),k=read();ch_add(l,r,k);
}else if(op==2){
ll l=read(),r=read();printf("%lld\n",ch_query(l,r)%p);
}else if(op==3){
ll r=read(),k=read();tre_add(r,k);
}else{
ll r=read();printf("%lld\n",tre_query(r)%p);
}
}
}
4. test picture
test math
/alpha
/beta
/gamma
/delta
\(\sum\sqrt[3]{\frac xy}{a+1\over b+1}\overrightarrow{xyz}\lim_{x\to 0}\)
\(\lim_{x \to 0} \frac {3x ^2 +7x^3} {x^2 +5x^4} = 3\)
\(\int_0^{+\infty} x^n e^{-x} dx = n!\)
标签:ch,return,int,ll,MAXN,test,id From: https://www.cnblogs.com/smy-2006/p/16745088.html