bzoj3531 Sdoi2014 旅行 樹剖

2021-08-07 21:22:04 字數 3594 閱讀 5487

對每種宗教都建立線段樹,建立過程類似主席樹,在需要修改時動態建立線段樹(初始時不建立),所以空間複雜度是o(

nlog

n)ps:為什麼第二份會t啊

#include

#include

#include

#define m 6000005

#define inf (1<<30)

using

namespace

std;

inline

int read()

while(ch>='0'&&ch<='9')

return x*f;

}int n,m,cnt,place,size;

int w[100005],c[100005],root[100005];

int fa[100005][17],deep[100005],pl[100005],belong[100005],son[100005];

int ls[m],rs[m],mx[m],sum[m];

struct datae[200005];int head[100005];

void ins(int u,int v)

#define bl belong

#define dep deep

#define pos pl

#define f fa

void dfs1(int u)

}void dfs2(int u,int chain)

if(k==0)return ;dfs2(k,chain);

for(int i=head[u];i;i=e[i].next)

}void update(int x)

void change(int &k,int l,int r,int x,int num)

int mid=(l+r)>>1;

if(x<=mid)change(ls[k],l,mid,x,num);

else change(rs[k],mid+1,r,x,num);

update(k);

}int askmx(int k,int l,int r,int x,int y)

int asksum(int k,int l,int r,int x,int y)

int solvesum(int x,int y,int c)

if(dep[x]>dep[y])swap(x,y);

sum+=asksum(root[c],1,n,pos[x],pos[y]);

return sum;

}int solvemx(int x,int y,int c)

if(dep[x]>dep[y])swap(x,y);

mx=max(mx,askmx(root[c],1,n,pos[x],pos[y]));

return mx;

}void solve()

else

}else

}}int main()

dfs1(1);dfs2(1,1);

solve();

return

0;}

#include

#include

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fod(i,a,b) for(int i=a;i>=b;i--)

using

namespace

std;

const

int n=1e5+10,m=6e6+10,inf=(1

<<30);

inline

int read()

while(ch>='0'&&ch<='9')

return x*f;

}int root[n],ls[m],rs[m],sum[m],mx[n],

dep[n],s[n],f[n],pos[n],bl[n],last[n],c[n],w[n],

size=0,len=0,cnt=0,n,q;

struct edge}e[n<<2];

void add_edge(int u,int v)

void dfs1(int u)

}void dfs2(int u,int chain)

if(k==0)return ;dfs2(k,chain);

for(int i=last[u];i;i=e[i].next)

}void update(int &k,int l,int r,int pos,int val)

int mid=(l+r)>>1;

if(pos<=mid)update(ls[k],l,mid,pos,val);

else update(rs[k],mid+1,r,pos,val);

sum[k]=sum[ls[k]]+sum[rs[k]];

mx[k]=max(mx[ls[k]],mx[rs[k]]);

}int query_sum(int k,int l,int r,int ql,int qr)

int mid=(l+r)>>1;

if(qr<=mid)return query_sum(ls[k],l,mid,ql,qr);

else

if(ql>mid)return query_sum(rs[k],mid+1,r,ql,qr);

else

return (query_sum(ls[k],l,mid,ql,mid)+query_sum(rs[k],mid+1,r,mid+1,qr));

}int query_mx(int k,int l,int r,int ql,int qr)

int mid=(l+r)>>1;

if(qr<=mid)return query_mx(ls[k],l,mid,ql,qr);

else

if(ql>mid)return query_mx(rs[k],mid+1,r,ql,qr);

else

return max(query_mx(ls[k],l,mid,ql,mid),query_mx(rs[k],mid+1,r,mid+1,qr));

}int solvesum(int x,int y,int c)

if(dep[x]>dep[y])swap(x,y);

sum+=query_sum(root[c],1,n,pos[x],pos[y]);

return sum;

}int solvemx(int x,int y,int c)

if(dep[x]>dep[y])swap(x,y);

mx=max(mx,query_mx(root[c],1,n,pos[x],pos[y]));

return mx;

}void solve()

else update(root[c[x]],1,n,pos[x],y),w[x]=y;

}else

}}int main()

for(int i=1,from,to;i1);dfs2(1,1);

solve();

return

0;}

BZOJ3531 旅行 樹鏈剖分

題目大意 給定一棵樹,點染色,修改點權,鏈上詢問點權和或者最大值 資料規模10 5 主要思想是對每種顏色開一顆線段樹,動態分配記憶體,染色時刪除原來的點,加入到新線段樹中即可。需要注意的是不僅插入要更新資訊,刪除也要更新資訊。自己的 include include define safe x,a x...

bzoj3531 樹刨 線段樹動態開點

題意 一棵樹,每個點有顏色,4種操作,1.單點修改權值 2.單點修改顏色 3.查詢路徑顏色相同的點權和 4.查詢路徑顏色相同的點權最大值。思路 樹刨 線段樹動態開點,開1e5個線段樹。include using namespace std define ll long long define for...

BZOJ 3531(樹鏈剖分 線段樹)

problem 旅行 bzoj 3531 題目大意 給定一顆樹,樹上的每個點有兩個權值 x,y 要求維護4種操作 操作1 更改某個點的權值x。操作2 更改某個點的權值y。操作3 求a b路徑上所有x屬性與a,b相同的點y屬性的和。操作4 求a b路徑上所有x屬性與a,b相同的點y屬性的最大值。n,q...