首页 > 编程语言 > 详细

COGS 577 蝗灾 cdq分治+树状数组

时间:2015-05-10 18:57:19      阅读:175      评论:0      收藏:0      [点我收藏+]

题目链接:点击打开链接

cdq入门资料:点击打开链接

思路:首先根据上面的ppt可知cdq分治:

solve(l, mid);

计算[l,mid] 对 [mid+1, r] 区间的影响

solve(mid+1, r);

计算影响部分,把询问拆成2个,对x排序后搞搞即可。


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <vector>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
const double eps = 1e-8;
const double pi = acos(-1.0);
template <class T>
inline bool rd(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF) return 0;
	while (c != '-' && (c<'0' || c>'9')) c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
	ret *= sgn;
	return 1;
}
template <class T>
inline void pt(T x) {
	if (x <0) { putchar('-'); x = -x; }
	if (x>9) pt(x / 10);
	putchar(x % 10 + '0');
}
using namespace std;
typedef long long ll;
int c[500005], maxn;
inline int Lowbit(int x){ return x&(-x); }
void add(int i, int x){
	while (i <= maxn) c[i] += x,i += Lowbit(i);
}
int sum(int x){//区间求和 [1,x]
	int ans = 0;
	for (int i = x; i ; i -= Lowbit(i))
		ans += c[i];
	return ans;
}
const int N = 200005;
struct Q{
	int op, x1, y1, x2, y2, z, num, ans;
}q[N], cc[N<<1];
bool cmp(const Q&x, const Q&y){
	if (x.x1 == y.x1)return x.op < y.op;
	return x.x1 < y.x1;
}
int w, n;
int top;
void solve(int l, int r){
	if (l == r)return;
	int mid = (l + r) >> 1;
	top = 0;
	for (int i = l; i <= mid; i++)if (q[i].op == 1)cc[top++] = q[i];
	for (int i = mid + 1; i <= r; i++){
		if (q[i].op == 2){
			cc[top++] = q[i];
			cc[top++] = q[i];
			cc[top - 2].x1--;
			cc[top - 1].x1 = q[i].x2;
			cc[top - 1].op = 3;
		}
	}
	sort(cc, cc + top, cmp);
	for (int i = 0; i < top; i++){
		if (cc[i].op == 1)
			add(cc[i].y1, cc[i].z);
		else if (cc[i].op == 2)
			q[cc[i].num].ans -= sum(cc[i].y2) - sum(cc[i].y1 - 1);
		else
			q[cc[i].num].ans += sum(cc[i].y2) - sum(cc[i].y1 - 1);
	}
	for (int i = 0; i < top; i++)
	if (cc[i].op == 1)
		add(cc[i].y1, -cc[i].z);
	solve(l, mid); solve(mid + 1, r);
}
int main(){
	freopen("locust.in", "r", stdin);
	freopen("locust.out", "w", stdout);
	rd(w); rd(n);
	maxn = w;
	for (int i = 1, x1, y1, x2, y2; i <= n; i++){
		q[i].num = i;
		rd(q[i].op);
		if (q[i].op == 1){
			rd(q[i].x1); rd(q[i].y1); rd(q[i].z);
		}
		else {
			rd(x1); rd(y1); rd(x2); rd(y2);
			q[i].x1 = min(x1, x2); q[i].y1 = min(y1, y2);
			q[i].x2 = max(x1, x2); q[i].y2 = max(y1, y2);
		}
	}
	solve(1, n);
	for (int i = 1; i <= n; i++)
	if (q[i].op == 2)pt(q[i].ans), putchar('\n');
	return 0;
}


COGS 577 蝗灾 cdq分治+树状数组

原文:http://blog.csdn.net/qq574857122/article/details/45623067

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!