树链剖析板子(P3384 【模板】轻重链剖分)
发布日期:2021-06-30 10:18:14
浏览次数:2
分类:技术文章
本文共 4652 字,大约阅读时间需要 15 分钟。
对 应 对应 对应
#includeusing namespace std;#define GO std::ios::sync_with_stdio(false)const int maxn=4e5+10;int n,m,root,w[maxn],mod;struct edge{ int to,nxt;}d[maxn]; int head[maxn],k=1;void add(int u,int v){ d[k].to=v,d[k].nxt=head[u],head[u]=k++;}int deep[maxn],siz[maxn],fa[maxn], son[maxn];void dfs1(int u,int f,int depth){ deep[u]=depth, fa[u]=f, siz[u]=1; int maxson=-1; for(int i=head[u];i;i=d[i].nxt) { int v=d[i].to; if( v==f ) continue; dfs1(v,u,depth+1); siz[u]+=siz[v]; if(siz[v]>maxson) maxson=siz[v],son[u]=v; }}int id[maxn],wn[maxn],top[maxn],cnt;void dfs2(int u,int ffa){ id[u]=++cnt, wn[cnt]=w[u], top[u]=ffa; if( son[u]==0 ) return; dfs2( son[u],ffa ); for(int i=head[u];i;i=d[i].nxt) { int v=d[i].to; if( v==fa[u] || v==son[u] ) continue; dfs2(v,v); }}struct tree{ int v,l,r,lazy;}a[maxn];void push_down(int p){ if( !a[p].lazy ) return; int len1=a[p<<1].r-a[p<<1].l+1, len2=a[p<<1|1].r-a[p<<1|1].l+1; a[p<<1].lazy = (a[p<<1].lazy + a[p].lazy)%mod; a[p<<1|1].lazy = (a[p<<1|1].lazy + a[p].lazy)%mod; a[p<<1].v=(a[p<<1].v+a[p].lazy*len1%mod)%mod; a[p<<1|1].v = (a[p<<1|1].v+a[p].lazy*len2%mod)%mod; a[p].lazy=0;}void build(int p,int l,int r){ a[p].l=l,a[p].r=r,a[p].lazy=0; if( l==r ) { a[p].v=wn[l]%mod; return; } int mid = l+r>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); a[p].v = (a[p<<1].v+a[p<<1|1].v)%mod;}void tree_add(int p,int l,int r,int k){ if( l<=a[p].l&&a[p].r<=r) { a[p].v=( (a[p].r-a[p].l+1) *k+a[p].v)%mod; a[p].lazy=(a[p].lazy+k)%mod; return; } push_down(p); int mid=a[p].l+a[p].r>>1; if(l<=mid) tree_add(p<<1,l,r,k); if(r>mid) tree_add(p<<1|1,l,r,k); a[p].v = (a[p<<1].v+a[p<<1|1].v)%mod;}int tree_ask(int p,int l,int r){ if( l<=a[p].l&&a[p].r<=r) return a[p].v; push_down(p); int mid=a[p].l+a[p].r>>1,ans=0; if(l<=mid) ans=(ans + tree_ask(p<<1,l,r) )%mod; if(r>mid) ans=(ans + tree_ask(p<<1|1,l,r) )%mod; return ans;}void tree_addpath(int x,int y,int k)//x到y的路上加上k{ while(top[x] != top[y]) { if( deep[ top[x] ] deep[y] ) swap(x,y); tree_add(1,id[x],id[y],k);}int tree_asksum(int x,int y){ int ans=0; while( top[x]!=top[y] ) { if( deep[ top[x] ] deep[y] ) swap(x,y); ans= (ans+tree_ask(1,id[x],id[y]) )%mod; return ans;}void tree_addroot(int root,int k){ tree_add(1,id[root],id[root]+siz[root]-1,k);}int tree_askrootsum(int root){ int ans=tree_ask(1,id[root],id[root]+siz[root]-1)%mod; return ans;}int main(){ GO; cin.tie(0); cout.tie(0); cin >> n >> m >> root >> mod; for(int i=1;i<=n;i++) cin >> w[i]; for(int i=1, l, r;i > l >> r; add(l,r); add(r,l); } dfs1(root,0,1); dfs2(root,root); build(1,1,n); for(int i=1, a1, a2, a3, a4;i<=m;i++) { cin >> a1; if( a1==1 ) { cin >> a2 >> a3 >> a4; tree_addpath(a2,a3,a4%mod); } else if( a1==2 ) { cin >> a2 >> a3; cout << tree_asksum(a2,a3) << "\n"; } else if( a1==3 ) { cin >> a2 >> a3; tree_addroot(a2,a3); } else { cin >> a2; cout << tree_askrootsum(a2) << "\n"; } } return 0;}
区间覆盖,区间加法
#includeusing namespace std;#define ls (rt<<1)#define rs (rt<<1|1)#define mid (l+r>>1)#define lson ls,l,mid#define rson rs,mid+1,rconst int maxn=2e5+10;int uu[maxn],vv[maxn],son[maxn],n;struct edge{ int to,nxt,w;}d[maxn]; int head[maxn],cnt=1;void add(int u,int v,int w){d[++cnt] = (edge){v,head[u],w},head[u]=cnt;}int siz[maxn],fa[maxn],deep[maxn],wt[maxn];void dfs1(int u,int father){ siz[u]=1,fa[u]=father,deep[u]=deep[father]+1; for(int i=head[u];i;i=d[i].nxt ) { int v=d[i].to; if( v==father ) continue; wt[v]=d[i].w; dfs1(v,u); siz[u]+=siz[v]; if( siz[son[u]] =L&&r<=R ) { if( type==1 ) laz1[rt] = a[rt] = val, laz2[rt]=0;//直接改变 else laz2[rt]+=val,a[rt]+=val; return; } if( r R ) return; push_down(rt,l,r); update(lson,L,R,val,type); update(rson,L,R,val,type); a[rt] = max( a[ls],a[rs] );}int ask(int rt,int l,int r,int L,int R){ if( l>=L&&r<=R ) return a[rt]; if( l>R||r deep[y] ) swap(x,y); update(1,1,n,id[x]+1,id[y],val,type);}int askmax(int x,int y){ int ans=0; while( top[x]!=top[y] ) { if( deep[top[x]] deep[y] ) swap(x,y); ans = max( ans,ask(1,1,n,id[x]+1,id[y] )); return ans;}int main(){ scanf("%d",&n); for(int i=1;i deep[uu[i]] ) swap(uu[i],vv[i] ); string type; while( cin >> type && type!="Stop" ) { int u,v,w; scanf("%d%d",&u,&v); if( type == "Change" ) { modify(uu[u],vv[u],v,1); // update( 1,1,n,id[uu[u]],id[uu[u]],v,1 ); } else if( type=="Cover" ) { scanf("%d",&w); modify(u,v,w,1); } else if( type=="Add" ) { scanf("%d",&w); modify(u,v,w,2); } else printf("%d\n",askmax(u,v)); }}
转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/107297190 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月23日 04时04分57秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
mysql——介绍及安装与基本用法
2019-04-30
MySQL数据库之索引
2019-04-30
MYSQL——事务操作+视图+存储引擎
2019-04-30
Mysql——完全备份+增量备份+备份恢复
2019-04-30
MySQL进阶查询(SELECT 语句高级用法)
2019-04-30
Mysql 之主从复制
2019-04-30
LVS负载均衡------NAT模式
2019-04-30
squid代理-----透明代理模式
2019-04-30
squid代理介绍----ACL控制应用+sarg日志分析+反向代理
2019-04-30
redis集群之主从模式+哨兵模式
2019-04-30
JavaScript原生开关灯效果
2019-04-30
企业邮箱如何申请注册,邮箱申请如何免费注册?
2019-04-30
微信企业邮箱,手机邮箱格式地址怎么写?
2019-04-30
公司如何申请企业邮箱,公司邮箱怎么申请,公司企业邮箱哪个好?
2019-04-30
电子邮箱账号怎么申请,怎样申请邮箱账号呢
2019-04-30
邮箱怎么发邮件,邮件发信量多少,职场新人怎么发汇报邮件呢?
2019-04-30
maven 多层次pom 新引入包,编译成功,还是没有将包引入到本地
2019-04-30
leetCode2 两数相加
2019-04-30