DLUTOJ #1306 Segment Tree?
Description
有一个N个整数的序列(每个数的初值为0)。每个数都是整数。你有M次操作。操作有两种类型:
——Add Di Xi 从第一个数开始每隔Di 个位置增加Xi
——Query Li Ri 回答当前序列Li项到Ri项的和
Input
两个数N和M,输入到文件结尾。以下M行每行的输入两种操作形式的一种。(1 <= N, M, Di, Xi, Li, Ri <= 100000, Li <= Ri )
Output
对于每组数据,输出每组的询问的结果。
Sample Input
Sample Output
HINT
Source
这道题出自2013年国家队候选队员罗剑桥的论文《浅谈分块思想在一类数据处理问题中的应用》,是罗原创的一道题。
这道题的解法是分块:
将整个区间从左往右每$\lceil\sqrt{n}\rceil$个分成一块。
更新:
将$ADD\quad D \ X$操作分成两类
- $D \ge \lceil\sqrt{n} \rceil$ 的$ADD$操作,直接更新序列相应位置上元素,并更新各元素所属块由这类$ADD$操作所贡献的和,复杂度是$O(\sqrt{n})$。
- $D < \lceil \sqrt{n} \rceil$ 的$ADD$操作,我们将它记录在数组$sum[1\dots\lceil \sqrt{n} \rceil -1]$上:即对于$ADD \quad D \ X$,将$X$累加在$sum[D]$上,复杂度是$O(1)$。
查询:
对于查询区间$[L, R]$,分别查询上述两类$ADD$操作对$[L, R]$的贡献,相加即是答案。
Implementation:
这题我调了很长时间,先贴上第一版(有bug)代码
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
const int N(1e5+);
int n, m, b;
LL bucket[N], sum[N], a[N];
char op[]; inline int ID(int x, int b){ //x>=0
return x? (x-)/b+: ;
} int main(){
for(int T=; ~scanf("%d%d", &n, &m); T++){
if(T==) for(;;);
memset(a, , sizeof(a));
memset(bucket, , sizeof(bucket));
memset(sum, , sizeof(sum));
b=sqrt(n);
for(int d, x, l, r; m--; ){
scanf("%s", op);
if(*op=='A'){
scanf("%d%d", &d, &x);
if(d>=b){
for(int i=; i<=n; i+=d)
a[i]+=x, bucket[ID(i, b)]+=x;
}
else sum[d]+=x;
}
else{
scanf("%d%d", &l, &r);
LL res=;
int L=ID(l-, b)+, R=ID(r+, b)-; //error-prone
////////////////////////////////////////
for(int i=l; i<=b*(L-); i++) res+=a[i];
for(int i=b*R+; i<=r; i++) res+=a[i];
////////////////////////////////////////
for(int i=L; i<=R; i++) res+=bucket[i];
for(int i=; i<b; i++){
res+=(ID(r, i)-ID(l-, i))*sum[i];
}
printf("%lld\n", res);
}
}
}
return ;
}
bug就在分离出来的那两行,坑暂时留着,以后填。
bug-free version
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
const int N(1e5+);
int n, m, b, id[N];
LL bucket[N], sum[N], a[N];
char op[]; LL SUM(int x){
LL res=;
int R=id[x+]-;
for(int i=; i<=R; i++) res+=bucket[i];
for(int i=R*b+; i<=x; i++) res+=a[i];
for(int i=; i<b; i++) res+=((x-)/i+)*sum[i];
return res;
} int main(){
for(; ~scanf("%d%d", &n, &m); ){
memset(a, , sizeof(a));
memset(bucket, , sizeof(bucket));
memset(sum, , sizeof(sum));
b=sqrt(n);
for(int i=; i<=n+; i++) id[i]=(i-)/b+;
for(int d, x, l, r; m--; ){
scanf("%s", op);
if(*op=='A'){
scanf("%d%d", &d, &x);
if(d>=b) for(int i=; i<=n; i+=d) a[i]+=x, bucket[id[i]]+=x;
else sum[d]+=x;
}
else scanf("%d%d", &l, &r), printf("%lld\n", SUM(r)-SUM(l-));
}
}
return ;
}
DLUTOJ #1306 Segment Tree?的更多相关文章
- BestCoder#16 A-Revenge of Segment Tree
Revenge of Segment Tree Problem Description In computer science, a segment tree is a tree data struc ...
- [LintCode] Segment Tree Build II 建立线段树之二
The structure of Segment Tree is a binary tree which each node has two attributes startand end denot ...
- [LintCode] Segment Tree Build 建立线段树
The structure of Segment Tree is a binary tree which each node has two attributes start and end deno ...
- Segment Tree Modify
For a Maximum Segment Tree, which each node has an extra value max to store the maximum value in thi ...
- Segment Tree Query I & II
Segment Tree Query I For an integer array (index from 0 to n-1, where n is the size of this array), ...
- Segment Tree Build I & II
Segment Tree Build I The structure of Segment Tree is a binary tree which each node has two attribut ...
- Lintcode: Segment Tree Query II
For an array, we can build a SegmentTree for it, each node stores an extra attribute count to denote ...
- Lintcode: Segment Tree Modify
For a Maximum Segment Tree, which each node has an extra value max to store the maximum value in thi ...
- Lintcode: Segment Tree Query
For an integer array (index from 0 to n-1, where n is the size of this array), in the corresponding ...
随机推荐
- jQuery Ajax 操作函数及deferred对象
jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据. 函数 描述 jQuery.ajax() 执行异步 H ...
- WP 8.1 中挂起时页面数据保存方式
1.保存到Applicaion Data配置信息中: 保存: private void testTB_TextChanged(object sender, TextChangedEventArgs e ...
- Linux ssh登录和软件安装详解
阿哲Style Linux第一天 ssh登录和软件安装详解 Linux学习第一天 操作环境: Ubuntu 16.04 Win10系统,使用putty_V0.63 本身学习Linux就是想在服务器 ...
- c语言 &取地址运算符的理解
对于c语言中的&运算符,百度百科是这样定义的:(&p)则是这样一种运算,返回当时声明p 时开辟的地址:但是根据我对代码的观察,我觉得&运算符不只是返回地址的功能: 例如: in ...
- XXOOJL
她的鞋子放在外面没拿进来很显眼,我们俩正抱在床上,刚做完什么也没穿,她也没擦.听到门外的脚步声.赶紧穿.她在我房间里没出声,但我父亲肯定看出来了.于是问我:母亲去哪了,然后他去找她. 太尴尬了,那晚我 ...
- 利用link标签的disabed属性大面积的对其他标签元素的CSS样式进行替换操作
由于平时对元素样式的控制基本上只是3,4个,所以一般用Jquery的时候直接使用$(element).css();这个方法,或者使用$(element).addClass()方法完成样式操作.对于小范 ...
- AutoLayout 约束与frame、bounds的设置
介绍 关于AutoLayout的介绍可参考: 使用解读: https://segmentfault.com/a/1190000004386278 iOS 屏幕适配,autoResizing autoL ...
- java中的自增问题
运行下面这段代码,其结果是什么呢? package com.test; public class Inc { public static void main(String[] args) { Inc ...
- SQL Serve允许远程连接的解决方法
(一)用户需要做的第一件事是检查SQL数据库服务器中是否允许远程链接.在SQL 2008服务器中可以通过打开SQL Server 2008管理项目(SQL Server 2008 Management ...
- 解放双手:如何在本地调试远程服务器上的Node代码
写在前面 谈到node断点调试,目前主要有三种方式,通过node内置调试工具.通过IDE(如vscode).通过node-inspector,三者本质上差不多.本文着重点在于介绍 如何在本地通过nod ...