BZOJ -3730(动态点分治)
题目:在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]。
不幸的是,这片土地常常发生地震,并且随着时代的发展,城市的价值也往往会发生变动。
接下来你需要在线处理M次操作:
0 x k 表示发生了一次地震,震中城市为x,影响范围为k,所有与x距离不超过k的城市都将受到影响,该次地震造成的经济损失为所有受影响城市的价值和。
1 x y 表示第x个城市的价值变成了y。
为了体现程序的在线性,操作中的x、y、k都需要异或你程序上一次的输出来解密,如果之前没有输出,则默认上一次的输出为0。
思路:点分树,动态维护一个重心的信息。 这里维护的是点到其他点的某距离下的权值和。 注意处理重复信息。
时间卡得有点紧,ST表求LCA,没树剖快。。。居然?
线段树没树状数组快,这个可以理解,关键是在于怎么开点,不会炸空间--------把空间和点分树的对应起来O(NlogN)就可以了。
(T了很多次,也改(抄)了不少写法,日后再来补。
- #include<bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define RG register
- #define MAX 111111
- inline int read()
- {
- RG int x=,t=;RG char ch=getchar();
- while((ch<''||ch>'')&&ch!='-')ch=getchar();
- if(ch=='-')t=-,ch=getchar();
- while(ch<=''&&ch>='')x=x*+ch-,ch=getchar();
- return x*t;
- }
- int n,m,V[MAX];
- struct Line{int v,next;}e[MAX<<];
- int h[MAX],cnt=;
- inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
- /********************************************************************/
- /*int size[MAX],dfn[MAX],top[MAX],dep[MAX],fa[MAX],tim,hson[MAX];
- void dfs1(int u,int ff)
- {
- fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1;
- for(int i=h[u];i;i=e[i].next)
- {
- int v=e[i].v;if(v==ff)continue;
- dfs1(v,u);size[u]+=size[v];
- if(size[v]>size[hson[u]])hson[u]=v;
- }
- }
- void dfs2(int u,int tp)
- {
- top[u]=tp;
- if(hson[u])dfs2(hson[u],tp);
- for(int i=h[u];i;i=e[i].next)
- if(e[i].v!=fa[u]&&e[i].v!=hson[u])
- dfs2(e[i].v,e[i].v);
- }
- int LCA(int u,int v)
- {
- while(top[u]^top[v])dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
- return dep[u]<dep[v]?u:v;
- }
- int Dis(int u,int v){return dep[u]+dep[v]-2*dep[LCA(u,v)];}*/
- bool vis[MAX];
- int ver[MAX<<],first[MAX<<],dept[MAX<<],Tot;
- int dp[MAX<<][],dep[MAX<<];
- void dfs(int u ,int d)
- {
- vis[u]=true;
- ver[++Tot] = u;
- first[u] = Tot;
- dept[Tot] = d; dep[u]=d;
- for(int i=h[u];i;i=e[i].next)
- if( !vis[e[i].v] )
- {
- dfs(e[i].v,d+);
- ver[++Tot] = u;
- dept[Tot] = d;
- }
- }
- void ST(int N)
- {
- for(int i=;i<=N;i++) dp[i][] = i;
- for(int j=;(<<j)<=N;j++)
- {
- for(int i=;i+(<<j)-<=N;i++)
- {
- int a = dp[i][j-] , b = dp[i+(<<(j-))][j-];
- dp[i][j] = dept[a]<dept[b]?a:b;
- }
- }
- }
- int lg2[MAX<<];
- int RMQ(int l,int r)
- {
- int k=;
- //while((1<<(k+1))<=r-l+1) k++;
- k=lg2[r-l+];
- int a=dp[l][k],b=dp[r-(<<k)+][k];
- return dept[a]<dept[b]?a:b;
- }
- int LCA(int u ,int v)
- {
- int x = first[u] , y = first[v];
- int res;
- if(x<=y) res = RMQ(x,y);
- else res=RMQ(y,x);
- //cout<<u<<" "<<v<<" : "<<ver[res]<<endl;
- return ver[res];
- }
- int Dis(int u,int v)
- {
- return dep[u]+dep[v]-(dep[LCA(u,v)]<<);
- }
- namespace BIT{
- typedef vector<int> vec;
- struct BIT{
- vec tree; int n;
- inline void init(int size) {tree.resize(size+); n=size+;}
- inline int lowbit(int x) {return x&-x;}
- inline void Modify(int x,int d) {if (x<=) return; for (int i=x; i<=n; i+=lowbit(i)) tree[i]+=d;}
- inline int Query(int x) {int re=; if (x>n) x=n; for (int i=x; i>; i-=lowbit(i)) re+=tree[i]; return re;}
- }G[MAX<<];
- }using namespace BIT;
- int Fa[MAX],Size,root,mx,size[MAX];
- void Getroot(int u,int ff)
- {
- size[u]=;int ret=;
- for(int i=h[u];i;i=e[i].next)
- {
- int v=e[i].v;if(v==ff||vis[v])continue;
- Getroot(v,u);size[u]+=size[v];
- ret=max(ret,size[v]);
- }
- ret=max(ret,Size-size[u]);
- if(ret<mx)mx=ret,root=u;
- }
- void DFS(int u,int ff)
- {
- vis[u]=true;Fa[u]=ff;
- for(int i=h[u];i;i=e[i].next)
- {
- int v=e[i].v;if(vis[v])continue;
- mx=Size=size[v];
- Getroot(v,u);
- G[root].init(Size); G[root+n].init(Size);
- DFS(root,u);
- }
- }
- void Modify(int x,int w)
- {
- G[x].Modify(,w);
- for(int i=x;Fa[i];i=Fa[i])
- {
- int dis=Dis(x,Fa[i]);
- G[Fa[i]].Modify(dis+,w);
- G[i+n].Modify(dis+,w);
- }
- }
- int Query(int x,int K)
- {
- int ret=G[x].Query(K+);
- for(int i=x;Fa[i];i=Fa[i])
- {
- int dis=Dis(x,Fa[i]);if(dis>K)continue;
- //ret+=Query(rt[Fa[i]],0,n,0,K-dis);
- //ret-=Query(rt[i+n],0,n,0,K-dis);
- ret+=G[Fa[i]].Query(K-dis+);
- ret-=G[i+n].Query(K-dis+);
- }
- return ret;
- }
- /********************************************************************/
- int main()
- {
- n=read();m=read();
- for(int i=;i<=n;++i)V[i]=read();
- for(int i=;i<n;++i)
- {
- int u=read(),v=read();
- Add(u,v);Add(v,u);
- }
- /*dfs1(1,0);dfs2(1,1);*/
- dfs(,);
- ST(Tot);
- lg2[]=-;
- for(int i=;i<=Tot;i++) lg2[i]=lg2[i>>]+;
- for(int i=;i<=n;i++) vis[i]=;
- Size=mx=n;
- Getroot(,); G[root].init(n); G[root+n].init(n);DFS(root,);
- for(int i=;i<=n;++i) Modify(i,V[i]);
- int ans=;
- while(m--)
- {
- int opt=read(),x=read()^ans,y=read()^ans;
- if(opt==)printf("%d\n",ans=Query(x,y));
- else Modify(x,y-V[x]),V[x]=y;
- }
- return ;
- }
BZOJ -3730(动态点分治)的更多相关文章
- 【BZOJ1095】捉迷藏(动态点分治)
[BZOJ1095]捉迷藏(动态点分治) 题面 BZOJ 题解 动态点分治板子题 假设,不考虑动态点分治 我们来想怎么打暴力: \(O(n)DP\)求树的最长链 一定都会.不想解释了 所以,利用上面的 ...
- 【BZOJ3730】震波(动态点分治)[复习]
题面 BZOJ 题解 动态点分治什么的完全不记得了.这回重新写一写. 首先我们把点分树给建出来. 操作只有两种,修改和询问距离某个点的距离不超过\(k\)的点的和. 两点之间的距离可以树链剖分之类的算 ...
- bzoj 3730: 震波 动态点分治_树链剖分_线段树
##### 题目描述 : 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着 ...
- BZOJ 3295 动态逆序对 | CDQ分治
BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= = 不得不说CLJ说得真的太简单了,实现方面根本没提. 首先我们可以先用树分治构建出这 ...
- BZOJ 3435 / Luogu 3920 [WC2014]紫荆花之恋 (替罪羊树 动态点分治 套 Treap)
题意 略 分析 引用PoPoQQQ的话 吾辈有生之年终于把这道题切了...QAQ (蒟蒻狂笑) Orz PoPoQQQ,我又抄PoPoQQQ的题解了 - 突然发现有旋Treap没那么难写 学习了一波C ...
- 【BZOJ4372】烁烁的游戏(动态点分治)
[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...
- 【BZOJ3730】震波(动态点分治)
[BZOJ3730]震波(动态点分治) 题面 BZOJ 题意 给定一棵树, 每次询问到一个点的距离\(<=K\)的点的权值之和 动态修改权值, 强制在线 题解 正常的\(DP\)??? 很简单呀 ...
- bzoj3730 震波 [动态点分治,树状数组]
传送门 思路 如果没有强制在线的话可以离线之后CDQ分治随便搞. 有了强制在线之后--可能可以二维线段树?然而我不会算空间. 然后我们莫名其妙地想到了动态点分治,然后这题就差不多做完了. 点分树有一个 ...
- BZOJ1095 [ZJOI2007]Hide 捉迷藏 动态点分治 堆
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ1095.html 题目传送门 - BZOJ1095 题意 有 N 个点,每一个点是黑色或者白色,一开始所 ...
随机推荐
- (转)Intellij IDEA 2017 debug断点调试技巧与总结详解篇
背景:详细介绍idea的debug调试过程 Intellij IDEA 2017 debug断点调试技巧与总结详解篇
- 2017ACM/ICPC广西邀请赛 Color it
Color it Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Tota ...
- 使用Android SDK卸载厂家程序
ADB下载: 官网翻墙比较慢,这里推荐使用国内网站:https://www.androiddevtools.cn/ 下载 SDK Tools 和 SDK Platform-Tools: 两者分别 ...
- [转载]ROS开发环境之Qt Creator
ROS开发环境之Qt Creator(http://my.phirobot.com/blog/2013-12-ros_ide_qtcreator.html) Created at: 2013-12-2 ...
- CF933E A Preponderant Reunion DP
传送门 题解搬运工 设原问题为问题A.每一次减少\(\min\{p_i , p_{i+1}\}\)难以处理,我们考虑将限制变得宽松一些:每一次可以减少\([1,\min\{p_i , p_{i+1}\ ...
- Oracle学习笔记(四)
Oracle中的体系结构: oracle体系结构中的进程: 共享池相关的优化: drop table t purge; create table t as select * from dba_obje ...
- Java jms学习
/** * <html> * <body> * <P> https://github.com/Jasonandy </p> * <p> Al ...
- C# 练习题 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?程序分析: 兔子的规律为数列1,1,2,3,5,8, ...
- "Sed" 高级实用功能汇总
sed命令有两个空间,一个叫pattern space,一个叫hold space.这两个空间能够证明人类的脑瓜容量是非常小的,需要经过大量的训练和烧脑的理解,才能适应一些非常简单的操作. 不信看下面 ...
- sqlserver 2005 数据库的差异备份与还原
找到一个可靠的步骤,点开链接:http://blog.csdn.net/kevindr/article/details/22154323