bzoj 1176: [Balkan2007]Mokia 【CDQ分治】

来源:互联网 发布:sass for mac中文版 编辑:程序博客网 时间:2024/05/16 09:33

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1176

题意:中文题

分析:题目要求一个子矩阵的所有权值和,我们可以将询问用容斥分成四块,

可以通过加加减减得到原矩阵;现在我们把这些询问都成了与修改一样的操作形式,

对于这些操作我们加入一个时间戳z,那么一个修改(x,y,z)会对询问(x1,y1,z1)产生影响的

必要条件就是x<=x1,y<=y1,z<=z1。那么我们对所有操作排个序,我们用cdq分治处理区间[l,r],mid=(l+r)>>1,

所有时间戳小于mid的修改都会对时间戳大于mid的询问产生影响,我们可以用树状数组求出。

排序处理x关系,剩下的就是y和z了,我们用树状数组处理y,cdq处理z。

代码:

#include <algorithm>#include <iostream>#include <iostream>#include <cstring>#include <cstdio>#include <string>#include <vector>#include <queue>#include <cmath>#include <stack>#include <set>#include <map>#include <ctime>#define INF 0x3f3f3f3f#define Mn 300010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul (u<<1)#define ur (u<<1)|1using namespace std;typedef long long ll;struct node {int x,y,z,val,id;node(){}node(int x,int y,int z,int val,int id):x(x),y(y),z(z),val(val),id(id){}bool operator <(const node a) const {if(x!=a.x) return x<a.x;if(y!=a.y) return y<a.y;return z<a.z;}}q[Mn],tmp[Mn];int bit[Mm];int n;int lowbit(int x) {return x&(-x);}void push(int x,int val) {if(x==0) return ;while(x<=n) {bit[x]+=val;x+=lowbit(x);}return ;}int sum(int x) {int re=0;while(x>0) {re+=bit[x];x-=lowbit(x);}return re;}int cnt;int ans[Mn];stack<pair<int,int> > sk;void cdq(int l,int r) {if(l==r) return ;int mid=(l+r)>>1;for(int i=l;i<=r;i++) {if(q[i].z<=mid&&!q[i].id) push(q[i].y,q[i].val),sk.push(make_pair(q[i].y,q[i].val));else if(q[i].z>mid&&q[i].id) ans[q[i].id]+=q[i].val*sum(q[i].y);}while(!sk.empty()) {        push(sk.top().first,-sk.top().second);        sk.pop();    }int L=l,R=mid+1;for(int i=l;i<=r;i++) {if(q[i].z<=mid) {tmp[L]=q[i];L++;} else {tmp[R]=q[i];R++;}}for(int i=l;i<=r;i++) q[i]=tmp[i];cdq(l,mid);cdq(mid+1,r);}int main() {   int m,w,x,id;int x1,x2,y1,y2;scanf("%d%d",&m,&n);cnt=id=0;while(scanf("%d",&x)) {if(x==1) {scanf("%d%d%d",&x1,&y1,&w);q[++cnt]=node(x1,y1,cnt,w,0);} else {if(x==3)break;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);ans[++id]+=(y2-y1+1)*(x2-x1+1)*m;q[++cnt]=node(x2,y2,cnt,1,id);q[++cnt]=node(x1-1,y1-1,cnt,1,id);q[++cnt]=node(x1-1,y2,cnt,-1,id);q[++cnt]=node(x2,y1-1,cnt,-1,id);}}sort(q+1,q+cnt+1);cdq(1,cnt);for(int i=1;i<=id;i++) {printf("%d\n",ans[i]);}    return 0;}


0 0
原创粉丝点击