2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 381 Solved: 163
[ Submit][ Status][ Discuss]
Description
你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:
命令 | 参数限制 | 内容 |
1 x y A | 1<=x,y<=N,A是正整数 | 将格子x,y里的数字加上A |
2 x1 y1 x2 y2 | 1<=x1<= x2<=N 1<=y1<= y2<=N | 输出x1 y1 x2 y2这个矩形内的数字和 |
3 | 无 | 终止程序 |
Input
输入文件第一行一个正整数N。
接下来每行一个操作。
Output
对于每个2操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
5
HINT
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
http://www.lydsy.com/JudgeOnline/problem.php?id=2683
把操作都离线出来,按x为第一关键字,y为第二关键字排序,按照读入顺序标记操作的顺序,在mid表示某个操作的时间,mid左边的操作就会影响mid右边的操作,如此进行cdq分治。查询操作拆成4个子操作。
还要继续巩固!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define Q q[tot]
const int maxn = 800000 +10;
struct Node{
int x, y, A, no, belong, op;
}q[maxn], tq[maxn];
int ans[maxn];
bool operator <(Node a, Node b){
if (a.x == b.x && a.y == b.y) return a.op < b.op;
if (a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
#define lowbit(x) (x&(-x))
int N;
int tree[maxn];
void update(int x, int v){
while(x <= N){
tree[x] += v;
x += lowbit(x);
}
}
int getsum(int x){
int sum = 0;
while(x > 0){
sum += tree[x];
x -= lowbit(x);
}
return sum;
}
void solve(int l, int r){
if (l == r) return;
int mid = (l+r)>>1;
for(int i = l ;i <= r; i++){
if (q[i].no <= mid && q[i].op == 1) update(q[i].y, q[i].A);
else if (q[i].no > mid && q[i].op == 2){
if (q[i].A){
ans[q[i].belong] += getsum(q[i].y);
}
else{
ans[q[i].belong] -= getsum(q[i].y);
}
}
}
for(int i = l; i <= r; i++){
if (q[i].no <= mid && q[i].op == 1) update(q[i].y, -q[i].A);
}
int l1 = l, l2 = mid + 1;
for(int i = l; i <= r; i++){
if (q[i].no <= mid) tq[l1++] = q[i];
else tq[l2++] = q[i];
}
for(int i = l; i <= r; i++){
q[i] = tq[i];
}
solve(l, mid); solve(mid+1, r);
}
int main()
{
// freopen("data.in", "r", stdin);
int T = 0, op, x, y, x1, y1, A, tot = 0;
scanf("%d", &N);
while(scanf("%d", &op) && op!=3){
if (op == 1){
scanf("%d%d%d", &x, &y, &A);
q[++tot].op = 1; Q.x = x; Q.y = y; Q.A = A; Q.no = tot;
}
else{
scanf("%d%d%d%d", &x, &y, &x1, &y1);
q[++tot].op = 2; Q.x = x-1; Q.y = y-1; Q.A = 1; Q.no = tot; Q.belong = ++T;
q[++tot].op = 2; Q.x = x-1; Q.y = y1; Q.A = 0; Q.no = tot; Q.belong = T;
q[++tot].op = 2; Q.x = x1; Q.y = y-1; Q.A = 0; Q.no = tot; Q.belong = T;
q[++tot].op = 2; Q.x = x1; Q.y = y1; Q.A = 1; Q.no = tot; Q.belong = T;
}
}
sort(q+1, q+1+tot);
solve(1, tot);
for(int i = 1; i <= T; i++){
printf("%d\n", ans[i]);
}
return 0;
}