洛谷3384&bzoj1036树链剖分
值得注意的是:
一个点的子树是存在一起的。。。也就是说我们修改子树的时候只用。。。
- /**************************************************************
- Problem: 1036
- User: Ez3real
- Language: C++
- Result: Accepted
- Time:3068 ms
- Memory:8112 kb
- ****************************************************************/
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cmath>
- #include<cstring>
- #include<algorithm>
- #define l(x) (x<<1)
- #define r(x) ((x<<1)|1)
- #define ll long long
- using namespace std;
- struct Treenode{int l,r;ll tag,val,mx;};
- struct Segtree
- {
- Treenode tr[*];
- void pushup(int id){tr[id].val=tr[l(id)].val+tr[r(id)].val;}
- void pushdown(int id)
- {
- tr[l(id)].val+=tr[id].tag*(tr[l(id)].r-tr[l(id)].l+);
- tr[r(id)].val+=tr[id].tag*(tr[r(id)].r-tr[r(id)].l+);
- tr[l(id)].tag+=tr[id].tag;tr[r(id)].tag+=tr[id].tag;
- tr[id].tag=;
- }
- void build(int id,int L,int R)
- {
- tr[id].l=L,tr[id].r=R;
- tr[id].tag=;
- if(L==R)return;
- int mid=(L+R)>>;
- build(l(id),L,mid);
- build(r(id),mid+,R);
- pushup(id);
- }
- void update(int id,int L,int R,ll k)
- {
- if(tr[id].l>=L && tr[id].r<=R)
- {
- tr[id].val+=k*(tr[id].r-tr[id].l+);
- tr[id].tag+=k;
- return;
- }
- if(tr[id].tag)pushdown(id);
- int mid=(tr[id].l+tr[id].r)>>;
- if(L<=mid)update(l(id),L,R,k);
- if(R>mid) update(r(id),L,R,k);
- pushup(id);
- }
- ll query(int id,int L,int R)
- {
- if(tr[id].l>=L && tr[id].r<=R)return tr[id].val;
- if(tr[id].tag)pushdown(id);
- int mid=(tr[id].l+tr[id].r)>>;
- ll ans=;
- if(L<=mid)ans+=query(l(id),L,R);
- if(R>mid)ans+=query(r(id),L,R);
- return ans;
- }
- }Seg;
- int first[],to[*],next[*];
- ll val[*],cnt;
- int size[],depth[],fa[],pos[],bl[],sz;
- inline void add(int u,int v){to[++cnt]=v;next[cnt]=first[u];first[u]=cnt;}
- int n,q,r,P;
- inline void dfs1(int u)
- {
- size[u]=;
- for(int i=first[u];i;i=next[i])
- {
- if(to[i]==fa[u])continue;
- depth[to[i]]=depth[u]+;
- fa[to[i]]=u;
- dfs1(to[i]);
- size[u]+=size[to[i]];
- }
- }
- inline void dfs2(int u,int idc)
- {
- int k=;
- sz++;
- pos[u]=sz;
- bl[u]=idc;
- for(int i=first[u];i;i=next[i])
- if(depth[to[i]]>depth[u] && size[to[i]]>size[k])
- k=to[i];
- if(k==)return;
- dfs2(k,idc);
- for(int i=first[u];i;i=next[i])
- if(depth[to[i]]>depth[u] && k!=to[i])
- dfs2(to[i],to[i]);
- }
- void tradd(ll x,ll v){Seg.update(,pos[x],pos[x]+size[x]-,v);}
- ll trq(ll x){return Seg.query(,pos[x],pos[x]+size[x]-)%P;}
- void Chainadd(ll x,ll y,ll v)
- {
- while(bl[x]!=bl[y])
- {
- if(depth[bl[x]]<depth[bl[y]]){x^=y;y^=x;x^=y;}
- Seg.update(,pos[bl[x]],pos[x],v);
- x=fa[bl[x]];
- }
- if(depth[x]<depth[y]){x^=y;y^=x;x^=y;}
- Seg.update(,pos[y],pos[x],v);
- }
- ll Qsum(ll u,ll v)
- {
- ll sum=;
- while(bl[u]!=bl[v])
- {
- if(depth[bl[u]]<depth[bl[v]]){u^=v;v^=u;u^=v;}
- (sum+=Seg.query(,pos[bl[u]],pos[u]))%=P;
- u=fa[bl[u]];
- }
- if(depth[u]<depth[v]){u^=v;v^=u;u^=v;}
- (sum+=Seg.query(,pos[v],pos[u]))%=P;
- return sum;
- }
- void Solve()
- {
- scanf("%d%d%d%d",&n,&q,&r,&P);
- for(int i=;i<=n;i++)scanf("%lld",&val[i]);
- for(int i=;i<n;i++)
- {
- int x,y;
- scanf("%d%d",&x,&y);
- add(x,y);
- add(y,x);
- }
- depth[r]=;
- dfs1(r);
- dfs2(r,r);
- Seg.build(,,n);
- for(int i=;i<=n;i++)Seg.update(,pos[i],pos[i],val[i]);
- for(int i=;i<=q;i++)
- {
- int opt;
- scanf("%d",&opt);
- if(opt==)
- {
- ll x,y,w;
- scanf("%lld%lld%lld",&x,&y,&w);
- Chainadd(x,y,w);
- }
- if(opt==)
- {
- ll x,y;
- scanf("%lld%lld",&x,&y);
- printf("%lld\n",Qsum(x,y));
- }
- if(opt==)
- {
- ll x,v;
- scanf("%lld%lld",&x,&v);
- tradd(x,v);
- }
- if(opt==)
- {
- ll x;
- scanf("%lld",&x);
- printf("%lld\n",trq(x));
- }
- }
- }
- int main()
- {
- Solve();
- return ;
- }
Luogu3384
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cmath>
- #include<cstring>
- #include<algorithm>
- #define l(x) (x<<1)
- #define r(x) ((x<<1)|1)
- #define ll long long
- using namespace std;
- struct Treenode{int l,r;ll tag,val,mx;};
- struct Segtree
- {
- Treenode tr[*];
- void pushup(int id){tr[id].val=tr[l(id)].val+tr[r(id)].val;tr[id].mx=max(tr[l(id)].mx,tr[r(id)].mx);}
- void build(int id,int L,int R)
- {
- tr[id].l=L,tr[id].r=R;
- if(L==R)return;
- int mid=(L+R)>>;
- build(l(id),L,mid);
- build(r(id),mid+,R);
- pushup(id);
- }
- void update(int k,int x,int y)
- {
- int l=tr[k].l,r=tr[k].r,mid=(l+r)>>;
- if(l==r){tr[k].val=tr[k].mx=y;return;}
- if(x<=mid)update(k<<,x,y);
- else update(k<<|,x,y);
- tr[k].val=tr[k<<].val+tr[k<<|].val;
- tr[k].mx=max(tr[k<<].mx,tr[k<<|].mx);
- }
- int query(int id,int L,int R)
- {
- if(tr[id].l>=L && tr[id].r<=R)return tr[id].val;
- int mid=(tr[id].l+tr[id].r)>>;
- int ans=;
- if(L<=mid)ans+=query(l(id),L,R);
- if(R>mid)ans+=query(r(id),L,R);
- return ans;
- }
- int Query(int id,int L,int R)
- {
- if(tr[id].l>=L && tr[id].r<=R)return tr[id].mx;
- int mid=(tr[id].l+tr[id].r)>>;
- int ans=-;
- if(L<=mid)ans=max(ans,Query(l(id),L,R));
- if(R>mid)ans=max(ans,Query(r(id),L,R));
- return ans;
- }
- }Seg;
- int first[],to[*],next[*],val[*],cnt;
- int size[],depth[],fa[],pos[],bl[],sz;
- inline void add(int u,int v){to[++cnt]=v;next[cnt]=first[u];first[u]=cnt;}
- inline void dfs1(int u)
- {
- size[u]=;
- for(int i=first[u];i;i=next[i])
- {
- if(to[i]==fa[u])continue;
- depth[to[i]]=depth[u]+;
- fa[to[i]]=u;
- dfs1(to[i]);
- size[u]+=size[to[i]];
- }
- }
- inline void dfs2(int u,int idc)
- {
- int k=;
- sz++;
- pos[u]=sz;
- bl[u]=idc;
- for(int i=first[u];i;i=next[i])
- if(depth[to[i]]>depth[u] && size[to[i]]>size[k])
- k=to[i];
- if(k==)return;
- dfs2(k,idc);
- for(int i=first[u];i;i=next[i])
- if(depth[to[i]]>depth[u] && k!=to[i])
- dfs2(to[i],to[i]);
- }
- int Qsum(int u,int v)
- {
- int sum=;
- while(bl[u]!=bl[v])
- {
- if(depth[bl[u]]<depth[bl[v]]){u^=v;v^=u;u^=v;}
- sum+=Seg.query(,pos[bl[u]],pos[u]);
- u=fa[bl[u]];
- }
- if(pos[u]>pos[v]){u^=v;v^=u;u^=v;}
- sum+=Seg.query(,pos[u],pos[v]);
- return sum;
- }
- int Qmax(int u,int v)
- {
- int mx=-;
- while(bl[u]!=bl[v])
- {
- if(depth[bl[u]]<depth[bl[v]]){u^=v;v^=u;u^=v;}
- mx=max(mx,Seg.Query(,pos[bl[u]],pos[u]));
- u=fa[bl[u]];
- }
- if(pos[u]>pos[v]){u^=v;v^=u;u^=v;}
- mx=max(mx,Seg.Query(,pos[u],pos[v]));
- return mx;
- }
- int n,q;
- void Solve()
- {
- scanf("%d",&n);
- for(int i=;i<n;i++)
- {
- int x,y;
- scanf("%d%d",&x,&y);
- add(x,y);
- add(y,x);
- }
- for(int i=;i<=n;i++)scanf("%d",&val[i]);
- dfs1();
- dfs2(,);
- Seg.build(,,n);
- for(int i=;i<=n;i++)Seg.update(,pos[i],val[i]);
- scanf("%d",&q);
- char ch[];
- for(int i=;i<=q;i++)
- {
- int x,y;scanf("%s%d%d",ch,&x,&y);
- if(ch[]=='C'){val[x]=y;Seg.update(,pos[x],y);}
- else
- {
- if(ch[]=='M')printf("%d\n",Qmax(x,y));
- else printf("%d\n",Qsum(x,y));
- }
- }
- }
- int main()
- {
- Solve();
- return ;
- }
bzoj1036
洛谷3384&bzoj1036树链剖分的更多相关文章
- 洛谷P3979 遥远的国度 树链剖分+分类讨论
题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...
- 洛谷 P4114 Qtree1 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 说明 思路 Change Query AC代码 总结 题面 题目链接 P4114 Qt ...
- [洛谷P3384] [模板] 树链剖分
题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=b ...
- 洛谷.4114.Qtree1(树链剖分)
题目链接 模板题都错了这么多次.. //边权赋到点上 树剖模板 //注意LCA.链的顶端不能统计到答案! #include <cstdio> #include <cctype> ...
- 洛谷 P3384 【模板】树链剖分
树链剖分 将一棵树的每个节点到它所有子节点中子树和(所包含的点的个数)最大的那个子节点的这条边标记为"重边". 将其他的边标记为"轻边". 若果一个非根节点的子 ...
- 树链剖分详解(洛谷模板 P3384)
洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...
- ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】
题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...
- BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...
- 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器
刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...
随机推荐
- vuforia 中摄像机的开启与关闭
本文主要讲解的是Unity对Vuforia的开发中在原生调用摄像头上遇到的坑~Unity中调用设备摄像头打开或则关闭,或则开关扫描识别问题等等一些情况~ 下面先说说趟过的坑,再说说解决办法,或则目前没 ...
- 自定义列表数据自动循环向下滚动view(类似于通知通报消息)
首先申明,这个自定义View不是本人写的,大神写的,本人仅限学习一级研究使用 直接上代码吧!后面我再解释一遍 package com.egojit.android.gcoa.views; import ...
- Idiomatic Phrases Game(图论最短路)
Idiomatic Phrases Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- 记录-spring MultipartFile 文件上传
注意:以下上传和下载方法未必完全正确,不同浏览器效果不同,建议不要使用IE /** * 简单的文件上传 * @author:qiuchen * @createTime:2012-6-19 * @par ...
- 如何更改CSDN博客高亮代码皮肤的样式,使博客看起来更有范(推荐)
由于本人写博客的时候,也没有配置博客的相关属性,因此贴出来的代码块都是CSDN默认的,因此代码背景色都是白色的,如下所示: 但是本人在浏览他人博客的时候,发现有些博客的代码块看起来比较有范,整个代码库 ...
- C#练习委托、事件、事件处理
控制台应用程序效果: 代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; ...
- mail
mail.php <?php require_once('class.phpmailer.php'); $mail = new PHPMailer(); //实例化 $mail->IsS ...
- swift ! 和 ? 的学习
刚开始学 这两个符号 不确定到底是否是可以互相替代 用的都混淆了 今天好好做个总结 如果声明一个变量 如下 var name:String? //只声明 没做初始化赋值 说明 当前name 是 n ...
- MySQL与Oracle的语法区别详细对比
MySQL与Oracle的语法区别详细对比 Oracle和mysql的一些简单命令对比在本文中将会涉及到很多的实例,感兴趣的你不妨学习一下,就当巩固自己的知识了 Oracle和mysql的一些简单 ...
- ELK日志分析系统-Logstack
ELK日志分析系统 作者:Danbo 2016-*-* 本文是学习笔记,参考ELK Stack中文指南,链接:https://www.gitbook.com/book/chenryn/kibana-g ...