HDU 3966 树链剖分后线段树维护
题意:
一棵树,
操作1.$path(a,b)$之间的点权$+k$
操作2.单点查询
题解:
树链剖分即可,注意代码细节,双向映射
主要是记录一下板子
#include <string.h>
#include <stdio.h>
#include <algorithm>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(ii,x) for(int ii=head[x];ii;ii=edge[ii].next)
using namespace std;
const int maxn=5e4+20,maxm=2e6+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
//head
int casn,n,m,k;
int num[maxn];
class segtree{public:
#define nd node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
int node[maxn*4],n;
int *mp;
void maketree(int s,int t,int now){
if(s==t){
nd=num[mp[s]];
return ;
}else nd=0;
maketree(s,(s+t)/2,now<<1);
maketree((s+t)/2+1,t,now<<1|1);
}
void init(int nn,int *mps){
n=nn;mp=mps;
maketree(1,n,1);
}
void update(int s,int t,int x){
update(s,t,x,1,n,1);
}
int query(int pos){
return query(pos,1,n,1);
}
void update(int s,int t,int x,int l,int r,int now=1){
if(s<=l&&t>=r) {
nd+=x;
return ;
}
ndl+=nd,ndr+=nd;nd=0;
int mid=(l+r)/2;
if(s<=mid) update(s,t,x,l,mid,now<<1);
if(t>mid) update(s,t,x,mid+1,r,now<<1|1);
}
int query(int pos,int l,int r,int now=1){
if(l==r) return nd;
ndl+=nd,ndr+=nd;nd=0;
int mid=(l+r)/2;
if(pos<=mid) return query(pos,l,mid,now<<1);
else return query(pos,mid+1,r,now<<1|1);
}
}tree;
namespace chain{
struct data_e{
int to,next;
}edge[maxn<<1];
int head[maxn],nume,mp[maxn];
inline void addedge(int a,int b){
edge[++nume]={b,head[a]};
head[a]=nume;
}
int ltop[maxn],fa[maxn],deep[maxn];
int sz[maxn],remp[maxn];
int son[maxn],cnt;
void init(){
rep(i,1,n) head[i]=0;
cnt=0,nume=1;
}
void dfs1(int now,int pre,int d){
deep[now]=d,fa[now]=pre,sz[now]=1,son[now]=0;
forn(i,now){
int to=edge[i].to;
if(to!=pre) {
dfs1(to,now,d+1);
sz[now]+=sz[to];
if(sz[to]>sz[son[now]]) son[now]=to;
}
}
}
void dfs2(int now,int pre,int sp){
ltop[now]=sp;mp[now]=++cnt;remp[cnt]=now;
if(son[now]) dfs2(son[now],now,sp);
forn(i,now){
int to=edge[i].to;
if(to!=son[now]&&to!=pre) dfs2(to,now,to);
}
}
void update(int a,int b,int val){
while(ltop[a]!=ltop[b]){
if(deep[ltop[a]]<deep[ltop[b]])swap(a,b);
tree.update(mp[ltop[a]],mp[a],val);
a=fa[ltop[a]];
}
if(deep[a]>deep[b])swap(a,b);
tree.update(mp[a],mp[b],val);
}
}; int main() {
while(~scanf("%d %d %d",&n,&m,&k)){
rep(i,1,n) scanf("%d",num+i);
chain::init();
while(m--){
int a,b;scanf("%d%d",&a,&b);
chain::addedge(a,b);
chain::addedge(b,a);
}
chain::dfs1(1,0,1);
chain::dfs2(1,1,1);
tree.init(n,chain::remp);
while(k--){
char x[10];int a,b,c;
scanf("%s",x);
if(x[0]=='Q'){
scanf("%d",&a);
printf("%d\n",tree.query(chain::mp[a]));
}else if(x[0]=='I'){
scanf("%d %d %d",&a,&b,&c);
chain::update(a,b,c);
}else {
scanf("%d %d %d",&a,&b,&c);
chain::update(a,b,-c);
}
}
}
}
HDU 3966 树链剖分后线段树维护的更多相关文章
- HDU 4366 Successor(树链剖分+zkw线段树+扫描线)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...
- poj 3237 Tree(树链剖分,线段树)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
- 【BZOJ3531】旅行(树链剖分,线段树)
[BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
- 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
- [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树
软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...
随机推荐
- 使用python对py文件程序代码复用度检查
#!/user/bin/env python # @Time :2018/6/5 14:58 # @Author :PGIDYSQ #@File :PyCheck.py from os.path im ...
- selenium中隐式等待和显示等待的区别
Selenium显示等待和隐式等待的区别1.selenium的显示等待原理:显示等待,就是明确的要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,那么久 ...
- ExcelPower_Helper插件功能简述与演示
部分功能演示简述: 1.文件目录浏览功能 此功能主要利用了ribbon的dynamicmenu控件,动态呈现自定义目录下的文件列表信息,支持点击打开,查看文件所在目录.功能来源于大神li ...
- React生命周期详解
React生命周期图解: 一.旧版图解: 二.新版图解: 从图中,我们可以清楚知道React的生命周期分为三个部分: 实例化.存在期和销毁时. 旧版生命周期如果要开启async rendering, ...
- Asp.Net Core中DI的知识总结
在asp.net core中DI的概念是由这几部分组成的: IServiceCollection,保存IServiceDescriptor实例的列表 IServiceProvider,只有一个方法Ge ...
- [转帖][超级少儿不宜]一氧化氮(NO),为什么亚洲人是最硬
阴茎科学:一氧化氮(NO),为什么亚洲人是最硬 尼堪巴图鲁 关注他 2,911 人赞同了该文章 https://zhuanlan.zhihu.com/p/55941740 超级少儿不宜.. ...
- python高级编程笔记一 正则表达式
事例
- Android List 排序
Collections.sort(list, (l1, l2) -> l1.getID().compareTo(l2.getID())); list:泛型集合 l1:比较的前一个泛型 l2:比较 ...
- 查看Linux的所有线程
查看Linux所有线程有3种方法: ps -T <pid>可以看指定pid的所有线程,SPID就是指线程.或者用ps -eLf top -H,和普通的top命令相比,多了Thread ht ...
- 使用ubuntu做为dotnet core开发环境
一.安装google浏览器 1.下载安装包(传送门:http://www.google.cn/intl/zh-CN/chrome/browser/desktop/index.html) 2.使用sud ...