树链剖分X2
1.ZJOI树的统计
板子题 因为初始化没打改了几个小时 改到双腿软着出的机房(身体素质感人
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define maxn 300000 #define ls x<<1 #define rs x<<1|1 using namespace std; ,v[maxn],top[maxn],son[maxn],fa[maxn],de[maxn],w[maxn],z,tree1[maxn],tree2[maxn],sz[maxn]; ]; struct eg { int to; int nxt; }b[maxn]; void link(int x,int y) { b[++tot].nxt=head[x]; b[tot].to=y; head[x]=tot; } void dfs1(int x,int f) { sz[x]=,fa[x]=f; ;i=b[i].nxt) { int t=b[i].to; if (t==f) continue; de[t]=de[x]+; dfs1(t,x); sz[x]+=sz[t]; ||sz[son[x]]<sz[t]) son[x]=t; } } void dfs2(int x,int tp) { top[x]=tp,w[x]=++z; ) dfs2(son[x],tp); else return ; ;i=b[i].nxt) { int t=b[i].to; if (t!=fa[x]&&t!=son[x]) dfs2(t,t); } } void build(int x,int l,int r) { tree2[x]=,tree1[x]=-; if (l==r) return ; ; build (ls,l,mid); build (rs,mid+,r); } void updata(int x,int l,int r,int d,int y) { if (l==r&&l==d) { tree1[x]=y; tree2[x]=y; return ; } ; if (d<=mid)updata(ls,l,mid,d,y); ,r,d,y); tree1[x]=max(tree1[ls],tree1[rs]); tree2[x]=tree2[ls]+tree2[rs]; } int qsum(int x,int l,int r,int ll,int rr) { if (ll==l&&r==rr) return tree2[x]; ; ,r,ll,rr); else if (rr<=mid) return qsum(ls,l,mid,ll,rr); ,r,mid+,rr); } int qmax(int x,int l,int r,int ll,int rr) { if (ll==l&&r==rr) return tree1[x]; ; if (rr<=mid) return qmax(ls,l,mid,ll,rr); ,r,ll,rr); ,r,mid+,rr)); } int find(int x,int y,int flag) { ) { ; int f1=top[x],f2=top[y]; while(f1!=f2) { if(de[f1]<de[f2]) swap(f1,f2),swap(x,y); ans=max(ans,qmax(,,z,w[f1],w[x])); x=fa[f1],f1=top[x]; } if (de[x]>de[y]) swap(x,y); ,,z,w[x],w[y])); } ) { ; int f1=top[x],f2=top[y]; while (f1!=f2) { if(de[f1]<de[f2]) swap(f1,f2),swap(x,y); ans+=qsum(,,z,w[f1],w[x]); x=fa[f1],f1=top[x]; } if (de[x]>de[y]) swap(x,y); ,,z,w[x],w[y]); } } int main() { memset(head, -, sizeof(head)); memset(son, -, sizeof(son)); scanf ("%d",&n); ;i<n;++i) { int x,y; scanf ("%d%d",&x,&y); link(x,y); link(y,x); } ;i<=n;++i) scanf ("%d",&v[i]); de[]=; dfs1(,); dfs2(,); build(,,z); ;i<=n;++i) updata(,,z,w[i],v[i]); int q; scanf("%d",&q); ;i<=q;++i) { scanf ("%s",s); int x,y; scanf ("%d%d",&x,&y); ]=='C') updata(,,z,w[x],y); ]=='M') printf()); ]=='S') printf()); } ; }
2.HAOI树上操作
这一次是被数组大小给困住了 好不容易反应过来开大了tree的大小结果我没有开大lazy的??(黑人问号
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define N 100002 #define LL long long #define ls x<<1 #define rs x<<1|1 using namespace std; ,df=; *N],to[*N],nxt[*N],dfn[N]; int sz[N],tp[N],son[N],de[N],fa[N],ed[N]; LL tree[*N],v[N],lazy[*N]; void link(int x,int y) { nxt[++tot]=head[x]; to[tot]=y; head[x]=tot; } void dfs(int x) { sz[x]=; for (int i=head[x];i;i=nxt[i]) { int t=to[i]; if (t==fa[x]) continue; de[t]=de[x]+; fa[t]=x; dfs(t); sz[x]+=sz[t]; if (sz[t]>sz[son[x]]) son[x]=t; } } void dfs1(int x,int top) { dfn[x]=++df,tp[x]=top; if (son[x]) dfs1(son[x],top); for (int i=head[x];i;i=nxt[i]) { int t=to[i]; if (t==fa[x]||t==son[x]) continue; dfs1(t,t); } ed[x]=df; } void down (int x,int l,int r) { ; tree[ls]+=lazy[x]*(mid-l+); tree[rs]+=lazy[x]*(r-mid); lazy[ls]+=lazy[x]; lazy[rs]+=lazy[x]; lazy[x]=; } void update(int x,int l,int r,int ll,int rr,LL w) { if (l!=r) down(x,l,r); if (ll<=l&&r<=rr) { tree[x]+=w*(r-l+); lazy[x]=w; return ; } ; if (ll<=mid) update(ls,l,mid,ll,rr,w); ,r,ll,rr,w); tree[x]=tree[ls]+tree[rs]; } LL query(int x,int l,int r,int ll,int rr) { if (l!=r) down(x,l,r); if (ll<=l&&r<=rr) return tree[x]; ; LL ans=; if (ll<=mid) ans+=query(ls,l,mid,ll,rr); ,r,ll,rr); return ans; } LL lca(int x) { LL ans=; ) { ans+=query(,,n,dfn[tp[x]],dfn[x]); x=fa[tp[x]]; } ans+=query(,,n,,dfn[x]); return ans; } int main() { scanf ("%d%d",&n,&m); ;i<=n;++i) scanf ("%lld",&v[i]); ;i<n;++i) { int x,y; scanf ("%d%d",&x,&y); link(x,y); link(y,x); } de[]=; dfs(),dfs1(,); ;i<=n;++i) update(,,n,dfn[i],dfn[i],v[i]); ;i<=m;++i) { //cout<<query(1,1,n,dfn[2],dfn[2])<<"**"<<endl; ; scanf ("%d",&fl); ) { int x,a; scanf ("%d%d",&x,&a); update(,,n,dfn[x],dfn[x],a); } ) { int x,a; scanf ("%d%d",&x,&a); update(,,n,dfn[x],ed[x],a); } ) { int x; scanf ("%d",&x); printf("%lld\n",lca(x)); } } ; }
最后再带上第一次在考试中(又是基本没学的状态下考的)遇到的树剖题
qtree系列中的一道
然而这个是强行lca做的 效果好像还可以啊
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define maxn 50000 using namespace std; ,he[maxn],nxt[maxn],to[maxn],di[maxn],de[maxn],dis[maxn]; bool vis[maxn]; ]; ]; void link(int x,int y,int dis) { nxt[++tot]=he[x]; to[tot]=y; di[tot]=dis; he[x]=tot; } void dfs(int u) { vis[u]=; for (int i=he[u];i;i=nxt[i]) { int t=to[i]; if (vis[t]) continue; f[t][]=u; de[t]=de[u]+; dis[t]=di[i]; dfs(t); } } void ff() { ;i<=));++i) ;j<=n;++j) f[j][i]=f[f[j][i-]][i-]; } int lca(int x,int y) { ; if (de[x]<de[y]) swap(x,y); int q=de[x]-de[y]; ,yy; ;(<<i)<=n;++i) <<i)) x=f[x][i]; ]) ans=max(ans,dis[i]); //cout<<ans<<"&&"<<endl; if (x==y) return ans; xx=x,yy=y; ));i>=;i--) { if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; } //cout<<x<<" "<<y<<"**"<<endl; ];i=f[i][]) ans=max(ans,dis[i]); ];i=f[i][]) ans=max(ans,dis[i]); return ans; } int main() { scanf ("%d",&n); ;i<n;++i) { int x,y,r; scanf ("%d%d%d",&x,&y,&r); link(x,y,r); link(y,x,r); } de[]=; dfs(); ff(); ) { scanf ("%s",s); ]=='D') break; ]=='C') { int x,y; scanf("%d%d",&x,&y); *x],yy=to[*x-]; //cout<<xx<<" "<<yy<<"&&"<<endl; ]==yy) dis[xx]=y; ]==xx) dis[yy]=y; } ]=='Q') { int x,y; scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } } ; }
树链剖分X2的更多相关文章
- 【BZOJ-3553】三叉神经树 树链剖分
3553: [Shoi2014]三叉神经树 Time Limit: 160 Sec Memory Limit: 256 MBSubmit: 347 Solved: 112[Submit][Stat ...
- Codeforces Round #329 (Div. 2) D. Happy Tree Party LCA/树链剖分
D. Happy Tree Party Bogdan has a birthday today and mom gave him a tree consisting of n vertecie ...
- Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分
D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...
- 3553: [Shoi2014]三叉神经树(树链剖分)
这道题特别恶心,首先我们可以发现更改的就是出现连续的一或二,那么就用线段树+树链剖分找到这个范围 想到是不难想,就是打起来恶心罢了= = CODE: #include<cstdio> #i ...
- D. Happy Tree Party CodeForces 593D【树链剖分,树边权转点权】
Codeforces Round #329 (Div. 2) D. Happy Tree Party time limit per test 3 seconds memory limit per te ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
随机推荐
- Jenkins与网站代码上线解决方案
1.1 前言 Jenkins是一个用Java编写的开源的持续集成工具.在与Oracle发生争执后,项目从Hudson项目独立. Jenkins提供了软件开发的持续集成服务.它运行在Servlet容器中 ...
- Less变量
Less变量 定义变量 Less 中的变量和其他编程语言一样,可以实现值的复用,同样它也有作用域(scope).简单的讲,变量作用域就是局部变量和全局变量的概念. Less 中,变量作用域采用的是就近 ...
- Python入门 - 生成随机数
生成随机数是编程中经常用到的功能,下面讲几种常用的随机函数randint,uniform, randrange: 一.生成随机整数 randint import random a = random. ...
- JAVA高并发程序设计笔记
第二章 Java并行程序基础 1.join()的本质是让调用线程wait()在当前线程的对象上 2.Thread.yiedl()会使当前线程让出CPU 3.volatile保证可见性,无法保证原子性( ...
- 51Nod--1018排序
1018 排序 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出N个整数,对着N个整数进行排序 Input 第1行:整数的数量N(1 <= N ...
- Golang 探索对Goroutine的控制方法
前言 在golang中,只需要在函数调用前加上关键字go即可创建一个并发任务单元,而这个新建的任务会被放入队列中,等待调度器安排.相比系统的MB级别线程栈,goroutine的自定义栈只有2KB,这使 ...
- Entity Framework Code First+SQL Server,改变聚集索引,提高查询性能
.net Entity Framework(调研的是Entity Framework 4.0) code first方式生成数据库时,不能修改数据库表的索引,而SQLServer默认会把数据表的主键设 ...
- bzoj4974 字符串大师
4974: 字符串大师 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 310 Solved: 155[Submit][Status][Discuss] ...
- tyvj4865 天天和树tree
#include<bits/stdc++.h> #define MAXN 100000+10 using namespace std; *MAXN]; ,head[MAXN],pre[MA ...
- 【Win 10 应用开发】MIDI 音乐合成——音符消息篇
在上一篇中,老周介绍了一些乐理知识,有了那些常识后,进行 MIDI 编程就简单得多了.尽管微软已经把 API 封装好,用起来也很简单,但是,如果你没有相应的音乐知识基础,你是无法进行 MIDI 编程的 ...