bzoj 4765: 普通计算姬
Description
Input
Output
Sample Input
0 0 3 4 0 1
0 1
1 2
2 3
2 4
3 5
5 6
2 1 2
1 1 1
2 3 6
2 3 5
Sample Output
10
9
HINT
思路
分块分块再分块,
假设块的长度是m,
可以先对编号分块,预处理出每个点对每一块的贡献(即这一块中有多少个x的祖先)。
这样时间复杂度n^2/m,空间复杂度n^2/m,为了不mle,m适宜<500。
这样修改操作就可以O(n/m)完成。
考虑询问操作,中间的完整块很好处理O(n/m),但左右端的残余块难处理。
可以扫残余块中的每个点,计算它们子树和的和,大约要计算m次子树和,即查询m次。
考虑怎样很快的计算子树和。
一种是log的做法,dfs序建树状数组,修改O(logn),查询O(logn)。但是这样查询多了一个log,不优。
考虑,每次操作,修改只进行了1次,查询进行了m次。所以考虑使修改变慢,查询变快。
所以,再对dfs序进行分块即可。这样修改O(n/m),查询1次O(1),非常优越。
时间复杂度n^2/m+nm=n*(n/m+m)。所以当m=sqrt(n)的时候,时间复杂度为O(n sqrt(n))
由于这种做法常数较大,虽然是O(n sqrt(n))的,有可能比那些带log的程序要慢(这也很尴尬啊)
代码
1 #include <cmath> 2 #include <cstdio> 3 #include <iostream> 4 using namespace std; 5 int read() 6 { 7 char c=getchar();int d=0,f=1; 8 for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; 9 for(;c>='0'&&c<='9';d=d*10+c-48,c=getchar()); 10 return d*f; 11 } 12 typedef unsigned long long ull; 13 typedef long long ll; 14 const int N=100002; 15 int M,n,m,cnt,tot; 16 int tmp[N],fa[N],bl[N],L[N],R[N],w[N*2],head[N],size[N],pos[N],t[320][N]; 17 ll s[N*2],bs[N*2],a[N*2]; 18 struct xint{int to,next;}e[N*2]; 19 inline void addedge(int x,int y) 20 { 21 e[++cnt]=(xint){y,head[x]}; 22 head[x]=cnt; 23 } 24 inline void add(int x,int s) 25 { 26 for(int i=R[x];i<=R[n];i+=M)a[i]+=s; 27 for(int i=x;i<=R[x]-1;++i)a[i]+=s; 28 } 29 inline ll ask(int x) 30 { 31 int A=pos[x]+size[x]-1,B=pos[x]-1; 32 return ((A%M)?a[L[A]-1]+a[A]:a[A])-((B%M)?a[L[B]-1]+a[B]:a[B]); 33 } 34 inline void dfs(int x) 35 { 36 tmp[bl[x]]++; 37 for(int i=1;i<=bl[n];++i)t[i][x]=tmp[i]; 38 pos[x]=++tot; 39 size[x]=1; s[x]=w[x]; 40 for(int i=head[x];i;i=e[i].next) 41 { 42 int y=e[i].to; 43 if(y==fa[x])continue; 44 fa[y]=x;dfs(y); 45 size[x]+=size[y]; 46 s[x]+=s[y]; 47 } 48 tmp[bl[x]]--; 49 } 50 inline void init() 51 { 52 n=read()+1,m=read(); 53 M=int(sqrt(n)); 54 for(int i=1;i<=n;++i)bl[i]=(i-1)/M+1; 55 for(int i=1;i<=n;++i)L[i]=bl[i]*M-M+1,R[i]=bl[i]*M; 56 for(int i=2;i<=n;++i)w[i]=read(); 57 for(int i=2;i<=n;++i) 58 { 59 int x=read()+1,y=read()+1; 60 addedge(x,y); 61 addedge(y,x); 62 } 63 dfs(1); 64 for(int i=1;i<=n;++i)bs[bl[i]]+=s[i]; 65 for(int i=1;i<=n;++i)add(pos[i],w[i]); 66 } 67 inline ull solve(int x,int y) 68 { 69 ull res=0; 70 if(bl[x]==bl[y]) 71 { 72 for(int i=x;i<=y;++i)res+=ask(i); 73 return res; 74 } 75 for(int i=x;i<=R[x];++i)res+=ask(i); 76 for(int i=L[y];i<=y;++i)res+=ask(i); 77 for(int i=bl[x]+1;i<=bl[y]-1;++i)res+=bs[i]; 78 return res; 79 } 80 inline void work() 81 { 82 while(m--) 83 { 84 int o=read(),x=read(),y=read(); 85 if(o==1) 86 { 87 x++; 88 ll dw=y-w[x]; 89 for(int i=1;i<=bl[n];++i) 90 bs[i]+=dw*t[i][x]; 91 add(pos[x],dw); 92 w[x]=y; 93 }else 94 if(o==2) 95 { 96 x++,y++; 97 ull ans=solve(x,y); 98 printf("%llu\n",ans); 99 } 100 } 101 } 102 int main() 103 { 104 init(); 105 work(); 106 }
转载于:https://www.cnblogs.com/Blog-of-Eden/p/6685423.html
bzoj 4765: 普通计算姬相关推荐
- bzoj 4765: 普通计算姬(分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Submit: 1481 Solved: 318 [Submit][Status][Disc ...
- bzoj 4765 普通计算姬
http://www.elijahqi.win/archives/3696 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬 ...
- BZOJ4765 普通计算姬
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ4766: 文艺计算姬
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 737 Solved: 402 [Submit][Status][Discuss] Descripti ...
- [BZOJ4766]文艺计算姬
[BZOJ4766]文艺计算姬 试题描述 "奋战三星期,造台计算机".小W响应号召,花了三星期造了台文艺计算姬.文艺计算姬比普通计算机有更多的艺术细胞.普通计算机能计算一个带标号完 ...
- Bzoj4766 文艺计算姬
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 234 Solved: 142 Description "奋战三星期,造台计算机" ...
- 省选专练之文艺计算姬
"奋战三星期,造台计算机".小W响应号召,花了三星期造了台文艺计算姬. 文艺计算姬比普通计算机有更多的艺术细胞. 普通计算机能计算一个带标号完全图的生成树个数,而文艺计算姬能计算一 ...
- linux 传输大文件大小,Linux大文件传输(转)
我们经常需要在机器之间传输文件.比如备份,复制数据等等.这个是很常见,也是很简单的.用scp或者rsync就能很好的完成任务.但是如果文件很大,需要占用一些传输时间的时候,怎样又快又好地完成任务就很重 ...
- ZJOI2019一轮停课刷题记录
Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...
最新文章
- PyTorch训练加速17种技巧
- tcp/ip通信中udp头部结构udphdrp-check校验计算
- 计算机应用基础2004年,计算机应用基础2004年下半年全国试题参考答案2
- JZOJ 3814. 【NOIP2014模拟9.7】天黑黑
- linux内存分配堆栈数据段代码段,linux – LD_PRELOAD堆栈和数据段内存分配
- textview点击展开全部或收起,内容过长显示省略号,设置行间距,字间距,跑马灯显示
- Active Directory备份与还原
- 打开SQlite数据库
- 2021年下种子磁力最好用的网盘
- 分站php源码,企业网站管理系统云优CMS v2.0.5 分站版
- 北京林业大学计算机考研录取分数线,北京林业大学信息学院计算机技术(专业学位)专业考研招生人数 考研报录比 考研复试分数线 考研辅导.pdf...
- Python 生成、识别社会统一信用代码
- Java中grabImage_JavaCV实现将视频以帧方式抽取
- Linux 下配置JDK 并运行springboot项目进行访问 Tomcat的安装
- JAVA移动垃圾分类车管理平台计算机毕业设计Mybatis+系统+数据库+调试部署
- Mybatis实现联合查询(六)
- 数据的经济价值与个人信息安全保护,该如何平衡?
- 个人怎么制作微信小程序,微信小程序可以免费制作吗?微信小程序制作教程
- (C)problem1:C语言阶乘求和
- WSL2 | ROS 安装