爲了記念在機房睡覺的第一個晚上~
今晚上開分塊~
順帶看看今晚能更多少
(2016年3月18日21:03:28)ios
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int MAXN = 1000000 + 5; int n,m; int num[MAXN]; int sum[MAXN]; int M; void init() { M = sqrt(n) + 1; for(int i = 0;i < n;i ++) sum[i / M] += num[i]; return; } void change(int x,int y) { num[x] += y; sum[x / M] += y; return; } int ask(int x,int y) { int ans = 0; while(x % M && x < y) ans += num[x ++]; while(y % M && y > x) ans += num[y --]; ans += num[y]; while(x < y) { ans += sum[x / M]; x += M; } return ans; } int q,a,b,v; int main() { scanf("%d",&n); for(int i = 0;i < n;i ++) scanf("%d",&num[i]); init(); scanf("%d",&m); for(int i = 1;i <= m;i ++) { scanf("%d",&q); switch(q) { case 1:scanf("%d %d",&a,&v);change(a - 1,v);break; case 2:scanf("%d %d",&a,&b);printf("%d\n",ask(a - 1,b - 1));break; } } return 0; }
第二題~
依然用分塊~
記得打標記
(2016年3月18日21:17:28)markdown
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int MAXN = 1000000 + 5; int n,m; int num[MAXN]; int sum[MAXN]; int add[MAXN]; int M; void init() { M = sqrt(n) + 1; for(int i = 0;i < n;i ++) sum[i / M] += num[i]; return; } void change(int x,int y,int v) { while(x % M && x < y) num[x ++] += v; while(y % M && y > x) num[y --] += v; num[y] += v; while(x < y) { add[x / M] += v; x += M; } return; } int ask(int x) { return num[x] + add[x / M]; } int q,a,b,v; int main() { scanf("%d",&n); for(int i = 0;i < n;i ++) scanf("%d",&num[i]); init(); scanf("%d",&m); for(int i = 1;i <= m;i ++) { scanf("%d",&q); switch(q) { case 1:scanf("%d %d %d",&a,&b,&v);change(a - 1,b - 1,v);break; case 2:scanf("%d",&a);printf("%d\n",ask(a - 1));break; } } return 0; }
第三題
總結出來的經驗就是想好什麼是針對塊的,什麼是針對元素的……
換句話說就是sum[x / M]
別寫成sum[x]
了……
DQS:「小兔子你個傻x」
2016年3月18日21:41:22spa
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long LL; const int MAXN = 1000000 + 5; int n,m; LL num[MAXN],sum[MAXN],add[MAXN]; int M; void init() { M = sqrt(n) + 1; for(int i = 0;i < n;i ++) sum[i / M] += num[i]; return; } void change(int x,int y,LL v) { while(x % M && x < y) { num[x] += v; sum[x / M] += v; x ++; } while(y % M && y > x) { num[y] += v; sum[y / M] += v; y --; } num[y] += v; sum[y / M] += v; while(x < y) { add[x / M] += v; sum[x / M] += v * M; x += M; } return; } LL ask(int x,int y) { LL ans = 0; while(x % M && x < y) ans += num[x] + add[x / M],x ++; while(y % M && y > x) ans += num[y] + add[y / M],y --; ans += num[y] + add[y / M]; while(x < y) { ans += sum[x / M]; x += M; } return ans; } int q,a,b; LL v; int main() { scanf("%d",&n); for(int i = 0;i < n;i ++) scanf("%lld",&num[i]); init(); scanf("%d",&m); for(int i = 1;i <= m;i ++) { scanf("%d",&q); switch(q) { case 1:scanf("%d %d %lld",&a,&b,&v);change(a - 1,b - 1,v);break; case 2:scanf("%d %d",&a,&b);printf("%lld\n",ask(a - 1,b - 1));break; } } return 0; }