[JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)
题目链接:
https://jzoj.net/senior/#contest/show/2529/1
题目:
题目背景:
尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门。他加入师门后发现有无穷无尽的师兄弟姐妹,这几天新副本开了,尊者神高达的师门作为一个 pve师门,于是他们决定组织一起去开荒。
题目描述:
师门可以看做以 1 为根的一棵树,师门中的每一个人都有一定的装备分数。一共会有 q 个事件。每个事件可能是一次开荒,也可能是因为开荒出了好装备而导致一个人的装分出现了变化。对于一次开荒,会有 k 个人组织,由于师门的号召力很强,所以所有在组织者中任意两个人简单路径上的人都会参加。
题目大意:
在树上给出多个点,每次询问包含这些点的最小连通块的点权之和,带修改
题解:
对于每一个询问,我们把点按照dfs序从小到大排序。画个图我们发现,假设当前点为第i个点,第i个点的贡献就是从第i个点到与第i-1个点的LCA上的路径上的点权和,但是不包括LCA的点权。为什么不包括LCA的点权呢?发现其实我们从第1个点到最终的LCA上的点权和(这个要算上最终的LCA)都没有计算,最后一起计算就是了
为什么是对的呢?我们考虑到排名靠后的点要么在上一个点的子树里,要么就是新开一个子树。对于前者我们发现公共LCA不上移,直接计算到上一个点的路径和就是了,而事实上上一个点和这个点的LCA就是上一个点。对于后者我们发现公共LCA发生上移,这在最终的答案被我们统计了进去。
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll; const int N=1e5+;
int n,Q,tot,tim;
int head[N],son[N],dep[N],fa[N][],dfn[N],id[N],sz[N],a[N];
ll val[N],t[N];
struct EDGE
{
int to,nxt;
}edge[N<<];
inline ll read()
{
char ch=getchar();
ll s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
void link(int u,int v)
{
edge[++tot]=(EDGE){v,head[u]};
head[u]=tot;
}
void dfs(int x,int pre)
{
sz[x]=;fa[x][]=pre;dfn[x]=++tim;id[tim]=x;
for (int i=;i<;i++) fa[x][i]=fa[fa[x][i-]][i-];
for (int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if (y==pre) continue;
dep[y]=dep[x]+;
dfs(y,x);
sz[x]+=sz[y];
}
}
void add(int x,ll y)
{
while (x<=n)
{
t[x]+=y;
x+=x&-x;
}
}
ll sum(int x)
{
ll re=;
while (x)
{
re+=t[x];
x-=x&-x;
}
return re;
}
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
for (int i=;i>=;i--) if (dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if (x==y) return x;
for (int i=;i>=;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][];
}
bool cmp(int a,int b){return dfn[a]<dfn[b];}
int main()
{
freopen("kaihuang.in","r",stdin);
freopen("kaihuang.out","w",stdout);
n=read();Q=read();
for (int i=;i<=n;i++) val[i]=read();
for (int i=,u,v;i<n;i++)
{
u=read();v=read();
link(u,v);link(v,u);
}
dep[]=;dfs(,);
//for (int i=1;i<=n;i++) printf("%d ",sz[i]);
//printf("\n");
for (int i=;i<=n;i++)
{
add(dfn[i],val[i]);add(dfn[i]+sz[i],-val[i]);
}
char op[];
for (int i=;i<=Q;i++)
{
scanf("%s",op);
if (op[]=='C')
{
int x=read();ll y=read();
add(dfn[x],-val[x]);add(dfn[x]+sz[x],val[x]);
val[x]=y;
add(dfn[x],y);add(dfn[x]+sz[x],-y);
}
if (op[]=='Q')
{
int k=;
while ()
{
int x=read();
if (!x) break;
a[++k]=x;
}
sort(a+,a++k,cmp);
if (k==)
{
printf("%lld\n",val[a[]]);
continue;
}
ll re=sum(dfn[a[]]);int LCA=a[];
for (int i=;i<=k;i++)
{
LCA=lca(LCA,a[i]);
re+=sum(dfn[a[i]]);
re-=sum(dfn[lca(a[i],a[i-])]);
}
re-=sum(dfn[fa[LCA][]]);
printf("%lld\n",re);
}
}
return ;
}
[JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)的更多相关文章
- [jzoj 5930] [NOIP2018模拟10.26】山花 解题报告 (质因数分类)
题目链接: http://172.16.0.132/senior/#contest/show/2538/2 题目: 小S决定从某一个节点$u$开始对其子树中与$u$距离小于$K$的节点代表的花树进行采 ...
- [JZOJ 5893] [NOIP2018模拟10.4] 括号序列 解题报告 (Hash+栈+map)
题目链接: https://jzoj.net/senior/#main/show/5893 题目: 题解: 考虑暴力怎么做,我们枚举左端点,维护一个栈,依次加入元素,与栈顶元素和栈内第二个元素相同时弹 ...
- [JZOJ 5905] [NOIP2018模拟10.15] 黑暗之魂(darksoul) 解题报告 (拓扑排序+单调队列+无向图基环树)
题目链接: http://172.16.0.132/senior/#main/show/5905 题目: oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰 ...
- [JZOJ 5885] [NOIP2018模拟9.27] 物理实验 解题报告 (思维)
题目链接: https://jzoj.net/senior/#main/show/5885 题目: 题解: 把$a$数组按升序排序 我们可以枚举$x$,发现对于任意$x$,最优情况下$y$一定等于$x ...
- [JZOJ 5909] [NOIP2018模拟10.16] 跑商(paoshang) 解题报告 (圆方树)
题目链接: https://jzoj.net/senior/#contest/show/2529/2 题目: 题目背景:尊者神高达很穷,所以他需要跑商来赚钱题目描述:基三的地图可以看做 n 个城市,m ...
- [JZOJ 5888] [NOIP2018模拟9.29] GCD生成树 解题报告 (最大生成树+公约数)
题目链接: http://172.16.0.132/senior/#main/show/5888 题目: 题解: 思路是这样的:两个数的最大公约数一定不会比这两个数的任意一个数大.因此我们把权值相等的 ...
- [jzoj 5926] [NOIP2018模拟10.25] naive 的图 解题报告(kruskal重构树+二维数点)
题目链接: https://jzoj.net/senior/#main/show/5926 题目: 题解: 显然最小的最大路径在最小生成树上(最小生成树=最小瓶颈生成树) 于是我们建出kruskal重 ...
- 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】
U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...
- 「模拟赛20180307」三元组 exclaim 枚举+树状数组
题目描述 给定 \(n,k\) ,求有多少个三元组 \((a,b,c)\) 满足 \(1≤a≤b≤c≤n\)且\(a + b^2 ≡ c^3\ (mod\ k)\). 输入 多组数据,第一行数据组数\ ...
随机推荐
- P1233 木棍加工
P1233 木棍加工 题目描述 一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的.棍子可以被一台机器一个接一个地加工.机器处理一根棍子之前需要准备时间.准备时间是这样定义的: 第一根棍子的准备时间 ...
- [Tomcat]Tomcat6和Tomcat7的区别
Tomcat 7最大的改进是对Servlet 3.0和Java EE 6的支持.◆Tomcat 7完全支持Servlet 3.0规范◆Tomcat 7新增了对Java注释的支持◆Tomcat 7通过w ...
- Session会在浏览器关闭后消失吗?
转 http://blog.csdn.net/rongwenbin/article/details/51784310 Cookie的两种类型 在项目开发中我们时常将需要在客户端(浏览器)缓存的数 ...
- 调试相关blogs收集
Debug Diag官方blog https://blogs.msdn.microsoft.com/debugdiag/ Tess https://blogs.msdn.microsoft.com ...
- C# 特性(Attribute)
C# 特性(Attribute) 特性(Attribute)是用于在运行时传递程序中各种元素(比如类.方法.结构.枚举.组件等)的行为信息的声明性标签.您可以通过使用特性向程序添加声明性信息.一个声明 ...
- 清北集训Day1T3 LYK loves jumping(期望DP)
题目描述 LYK在玩一个魔法游戏,叫做跳跃魔法. 有n个点,每个点有两个属性hi和ti,表示初始高度,和下降高度.也就是说,它初始时高度为hi,一旦LYK踩在这个点上,由于重力的影响,这个点的高度会下 ...
- 查看md文件
使用命令将md文件转为html,在浏览器中演示 通过npm安装i5ting_toc 安装好node之后,可以直接使用npm.Windows+R打开运行框,输入cmd,打开命令窗口.连网的情况下,输入如 ...
- 一个javascript面试题解析
; function fn(){ console.log(this.length); } var obj = { length: , method: function (fn) { fn(); // ...
- 算法 之 aabb
题目描述:输出所有形如aabb的4位完全平方数(即前两位数字相等,后两位数字也相等). 分支和循环结合在一起时功能强大: 下面列举所有可能的结果aabb,然后判断它们是否为完全平方数.注意a的范围是1 ...
- Oracle自制事务
数据库事务是一种单元操作,要么全部操作成功,要么全部失败.在Oracle中,一个事务是从执行第一个数据操作语言(DML)语句开始的,直到执行一个COMMIT语句,提交保存事务,或执行一个ROLLBAC ...