Ural 2062:Ambitious Experiment(树状数组 || 分块)
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 ;
}
Ural 2062:Ambitious Experiment(树状数组 || 分块)的更多相关文章
- ural Ambitious Experiment 树状数组
During several decades, scientists from planet Nibiru are working to create an engine that would all ...
- BZOJ_2141_排队_树状数组+分块
BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...
- 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分
题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...
- ural 2062 Ambitious Experiment
2062. Ambitious Experiment Time limit: 3.0 secondMemory limit: 128 MB During several decades, scient ...
- bzoj 4765 普通计算姬(树状数组 + 分块)
http://www.lydsy.com/JudgeOnline/problem.php?id=4765 很nice的一道题啊(可能是因为卡了n久终于做出来了 题意就是给你一棵带点权的有根树,sum( ...
- COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)
题目链接: COGS.BZOJ3236 Upd: 树状数组实现的是单点加 区间求和,采用值域分块可以\(O(1)\)修改\(O(sqrt(n))\)查询.同BZOJ3809. 莫队为\(O(n^{1. ...
- ACM-ICPC 2018 沈阳赛区网络预赛 J. Ka Chang(树状数组+分块)
Given a rooted tree ( the root is node 1 ) of N nodes. Initially, each node has zero point. Then, yo ...
- 【BZOJ2141】排队 树状数组+分块
[BZOJ2141]排队 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备 ...
- Codeforces Round #404 (Div. 2) A,B,C,D,E 暴力,暴力,二分,范德蒙恒等式,树状数组+分块
题目链接:http://codeforces.com/contest/785 A. Anton and Polyhedrons time limit per test 2 seconds memory ...
随机推荐
- ThreadPoolExecutor原理和使用
大家先从ThreadPoolExecutor的整体流程入手: 针对ThreadPoolExecutor代码.我们来看下execute方法: public void execute(Runnable c ...
- SyncML协议简述(和HTTP协议有点类似)
目前,移动计算和通信设备的流行很大部分原因是因为它们具有一些方便的功能,比如说在需要时可以发送信息给其他用户,用户希望随时随地都可以利用掌上设备访问信息和执行应用程序,甚至在飞行中也可以获得和更新信息 ...
- php获取一个月前的时间戳,获取三个月前的时间戳,获取一年前的时间戳
strtotime 非常强大的一个获取时间戳的函数 php获取一个月前的时间戳: strtotime("-0 year -1 month -0 day"); php获取三个月前的时 ...
- WPF 简单的绕圈进度条(无cs代码)
方案: 图标位置不变化的情况下设置透明度实现 代码: <Window x:Class="WpfApp1.MainWindow" xmlns="http://sche ...
- Delphi Android 将Google ZXing 整合(调用Jar文件)
前篇文章介绍了在delphi App(以下简称App)中可使用intent来调用Google ZXing 条码扫描器(以下简称zx),其各有优缺点,优点是我们不需关注zx本身的细节,只需调用其接口即可 ...
- vs2017 cordova调试ios app
https://docs.microsoft.com/en-us/visualstudio/cross-platform/tools-for-cordova/first-steps/ios-guide ...
- Oracle 存储过程创建及调用
--------创建存储过程------- create or replace procedure TestSPas begin update table_name set CREATE_TIMEST ...
- 解决win10开机出现recovery there was a problem with a device connected to your pc
问题描述: 开机无限重启并提示 recovery there was a problem with a device connected to your PC An unexpected I/O er ...
- 深入理解Java G1垃圾收集器
本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么 ...
- Libra 加密稳定币:Facebook的"野心"?
2008年11月1日,有一个传说叫中本聪的日裔美国人,发表了一篇名为<比特币:一种点对点式的电子现金系统>的论文.2009年,比特币出世,从此开启了电子货币这个收割机器,全世界的韭菜都是一 ...