http://acm.timus.ru/problem.aspx?space=1&num=2062

题意:有n个数,有一个值,q个询问,有单点询问操作,也有对于区间[l,r]的每个数i,使得num[i] + w, num[i*2] + w, num[i*3] + w……

思路:有树状数组和分块两种做法,对比后分块的速度比较快(暴力的艺术)。线段树会超时(可能写法不好)。

1、树状数组用到的是单点询问区间修改,我要注意一下其写法...修改为:Add(l, w), Add(r + 1, -w); 查询为:Sum(w);

bit[]维护增加的值,每次询问的时候只要去查询该位置的所有因子的位置增加的值,还有加上本来的数字就可以了。

2、分块的做法也是类似,因为单点修改的时候增加的值不能直接加在原来的num上,所以要多开一个every数组来记录单点修改。

查询的时候每个位置就是every[i] + block[belong[i]]。

也要注意一下分块的写法= =。

先判断是否在同一块,如果在同一块就暴力扫而不是直接block+w,因为L和R不一定在边界。。。

分块:

 #include <bits/stdc++.h>
using namespace std;
#define N 300010
typedef long long LL;
LL cnt, sz, block[N], every[N], l[N], r[N], belong[N], num[N], n, q; void Build() {
sz = sqrt(n);
cnt = n / sz; if(n % sz) cnt++;
for(int i = ; i <= cnt; i++)
l[i] = (i - ) * sz + , r[i] = i * sz;
r[cnt] = n;
for(int i = ; i <= n; i++)
belong[i] = (i - ) / sz + ;
} void Update(int L, int R, int w) {
if(belong[L] == belong[R])
for(int i = L; i <= R; i++) every[i] += w;
else {
for(int i = L; i <= r[belong[L]]; i++) every[i] += w;
for(int i = belong[L] + ; i <= belong[R] - ; i++) block[i] += w;
for(int i = l[belong[R]]; i <= R; i++) every[i] += w;
}
} LL solve(int n) {
int tmp = sqrt(n); LL ans = ;
for(int i = ; i <= tmp; i++) {
if(n % i == ) {
ans += block[belong[i]] + every[i];
if(i != n / i) ans += block[belong[n/i]] + every[n/i];
}
}
return ans;
} int main() {
ios::sync_with_stdio(false);
cin >> n;
for(int i = ; i <= n; i++) cin >> num[i];
Build();
cin >> q;
while(q--) {
int l, r, w, kind;
cin >> kind;
if(kind == ) {
cin >> w;
cout << solve(w) + num[w] << '\n';
cout.flush();
} else {
cin >> l >> r >> w;
Update(l, r, w);
}
}
}

树状数组:

 #include <bits/stdc++.h>
using namespace std;
#define N 300010
typedef long long LL;
LL bit[N], num[N];
int n, q;
// 区间更新,单点查询
int lowbit(int x) { return x & (-x); }
void Add(int x, int w) { for(int i = x; i <= n; i += lowbit(i)) bit[i] += w; }
LL Sum(int x) { LL ans = ; for(int i = x; i; i -= lowbit(i)) ans += bit[i]; return ans; }
LL solve(int n) {
int tmp = sqrt(n); LL ans = ;
for(int i = ; i <= tmp; i++) {
if(n % i == ) {
ans += Sum(i);
if(i != n / i) ans += Sum(n / i);
}
}
return ans;
} int main() {
ios::sync_with_stdio(false);
cin >> n;
for(int i = ; i <= n; i++) cin >> num[i];
cin >> q;
while(q--) {
int kind, l, r, w;
cin >> kind;
if(kind == ) {
cin >> w;
cout << solve(w) + num[w] << '\n';
cout.flush();
} else {
cin >> l >> r >> w;
Add(l, w); Add(r + , -w);
}
}
return ;
}

最新文章

  1. JS中的对象
  2. 用ProxyFactoryBean创建AOP代理
  3. 【图像处理】【SEED-VPM】1.板子基本操作流程
  4. Python自动化 【第十五篇】:CSS、JavaScript 和 Dom介绍
  5. WebDAV 配置及相关工具
  6. C#中字典集合HashTable、Dictionary、ConcurrentDictionary三者区别
  7. How to build windows azure PowerShell Source Code
  8. AsynTask用法
  9. 241. Different Ways to Add Parentheses——本质:DFS
  10. POJ 1861 Network (MST)
  11. ORACLE 基础知识积累
  12. 最全的微软msdn原版windows系统镜像和office下载地址集锦
  13. 基于Minifilter框架的文件过滤驱动理解
  14. ssd可以用作redo 盘吗?
  15. Linux - 简明Shell编程07 - 数组(Array)
  16. Java面向对象 继承(上)
  17. 浅析开源数据库MySQL架构
  18. CSS中各种居中的问题
  19. 【Spark篇】---SparkSQL中自定义UDF和UDAF,开窗函数的应用
  20. js中new函数后带括号和不带括号的区别

热门文章

  1. Angular route传参
  2. MIS的趋势必定是围绕机器取代人手,分工越来越细(小餐厅都支持微信自助点餐,结账时就打个折,相当于省了1、2个人手,SQL发明以后,程序员的工作更多了)
  3. WPF 使用Propereties:Resources.resx里面的资源
  4. Bootstrap按钮组 按钮工具栏 嵌套
  5. jquery对象及页面加载完成写法
  6. jquery 复选框操作-prop()的使用
  7. 枚举与字符串转及RecordSet转XML,JSON
  8. C++成员函数指针错误用法警示(成员函数指针与高性能的C++委托,三篇),附好多评论
  9. SpringBoot简易搭建
  10. Winform 点击TreeView控件节点的CheckBox不触发NodeMouseClick事件的做法