BZOJ 4765 普通计算姬 dfs序+分块+树状数组+好题!!!
2024-09-04 13:40:12
真是道好题。。。感到灵魂的升华。。。
按dfs序建树状数组,拿前缀和去求解散块;
按点的标号分块,分成一个个区间,记录区间子树和 的 总和。。。
具体地,需要记录每个点u修改后,对每一个块i的贡献,记为t[u][i]
计算思路:dfs时,每到一个新的点,就让++c[其所在块],为了记录每个块中的点出现过几次,就相当于记录这个点 被每一块中的点 包含了几次 , 然后for一遍,记录t[u][i]=c[i]
当修改一个点时,这个块的和+=这个点u对块i的贡献*这个点的变化量,即sum[i]+=t[u][i]*(v-a[u]);
#include<cstdio>
#include<iostream>
#include<cmath>
#define ll unsigned long long
#define R register ll
using namespace std;
const int N=;
inline ll g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m,q,T,cnt,num,rt;
int vr[N<<],nxt[N<<],a[N],fir[N],dfn[N],l[N],r[N],c[],t[N][],pos[N];
ll w[N],sum[];
inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
inline int lbt(int x) {return x&-x;}
inline void inc(int pos,ll d) {for(;pos<=n;pos+=lbt(pos)) w[pos]+=d;}
inline ll query(int pos) { R ret=;
for(;pos;pos-=lbt(pos))
ret+=w[pos]; return ret;
}
void dfs(int u) { l[u]=++num,++c[pos[u]]; inc(num,a[u]);
for(R i=;i<=pos[n];++i) t[u][i]=c[i];
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(l[v]) continue; dfs(v);
} r[u]=num,--c[pos[u]];
}
signed main() {
n=g(),q=g(); T=sqrt(n); m=(n%T)?n/T+:n/T;
for(R i=;i<=n;++i) a[i]=g(); for(R i=;i<=n;++i) pos[i]=(i-)/T+;
for(R i=,u,v;i<=n;++i) {u=g(),v=g(); if(!u) rt=v; else add(u,v),add(v,u);}
dfs(rt);
for(R i=;i<=pos[n];++i) for(R j=(i-)*T+,lim=min(i*T,(ll)n);j<=lim;++j) sum[i]+=query(r[j])-query(l[j]-);
for(R i=;i<=q;++i) {
R k=g(),u=g(),v=g();
if(k&) {
inc(l[u],v-a[u]);
for(R i=;i<=pos[n];++i) sum[i]+=1ull*t[u][i]*(v-a[u]);
a[u]=v;
} else { R ret=;
if(pos[u]==pos[v]) for(R i=u;i<=v;++i) ret+=query(r[i])-query(l[i]-);
else {
for(R i=u;i<=pos[u]*T;++i) ret+=query(r[i])-query(l[i]-);
for(R i=(pos[v]-)*T+;i<=v;++i) ret+=query(r[i])-query(l[i]-);
} for(R i=pos[u]+;i<pos[v];++i) ret+=sum[i]; printf("%llu\n",ret);
}
}
}
这题真神仙。。2019.04.23
最新文章
- 初步进行vs单元测试
- Python之路【第六篇】python基础 之面向对象(一)
- Asp.Net MVC<;九>;:OWIN,关于StartUp.cs
- 动态选路、RIP协议&;&;OSPF协议详解
- 使linux服务器默认使用中文字符集zh_CN.UTF-8
- [题解]UVa 10891 Game of Sum
- Win10安装framework3.5
- Python中时间的处理之——timedelta篇
- Valgrind使用[转]
- 05文件与IO
- hdu-5690 All X(快速幂+乘法逆元)
- 深入浅出JMS(二)——JMS的组成
- POJ1258-Agri-Net-ACM
- MSDN 杂志:UI 前沿技术 - WPF 中的多点触控操作事件
- Delphi中TApplication详解
- 每天一个Linux命令(09)--touch命令
- IScroll5不能滑到最底端的解决办法
- https://www.cnblogs.com/h2zZhou/p/5440271.html
- OZCode
- Python小白学习之路(二)—【Pycharm安装与配置】【创建项目】【运算符】【数据类型】