解題思路
CDQ模板,三維偏序問題。
第一維排序,第二維分治,第三維隨便一個數據結構,這裏用的是樹狀數組。
代碼:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
struct xw {int cl[5],ans;} wt[200005];
struct event{
int x,y,ans;
int val,num;
bool operator <(const event &p) const{
return num<p.num;
}
}s[800005],tmp[800005];
int a[2000005];
int si,n,tot,lo;
void add(int num,int x){ for(int i=num;i<=n;i+=i&(-i)) a[i]+=x;}
int ch(int num){
int j=0;
for(int i=num;i>0;i-=i&(-i)) j+=a[i];
return j;
}
void CDQ(int x,int y){
if(x==y) return ;
int mid=(x+y)>>1;
CDQ(x,mid);CDQ(mid+1,y);
int j=x;
for(int i=mid+1;i<=y;i++){
if(!s[i].val) continue;
while(j<=mid){
if(s[j].val) j++;
else if(s[j].y<=s[i].y) {add(s[j].x,s[j].ans);j++;}
else break;
}
s[i].ans+=ch(s[i].x);
}
for(int i=x;i<j;i++) if(!s[i].val) add(s[i].x,-s[i].ans);
int tp=x,zi=x,zj=mid+1;
while(zi<=mid && zj<=y){
if(s[zi].y<=s[zj].y) {tmp[tp++]=s[zi];zi++;}
else {tmp[tp++]=s[zj];zj++;}
}
while(zi<=mid) {tmp[tp++]=s[zi];zi++;}
while(zj<=y) {tmp[tp++]=s[zj];zj++;}
for(int i=x;i<=y;i++) s[i]=tmp[i];
}
int main(){
int opt,x1,x2,y1,y2;
scanf("%d%d",&si,&n);
while(scanf("%d",&opt)==1){
if(opt==1){
tot++;s[tot].val=0;
scanf("%d%d%d",&s[tot].x,&s[tot].y,&s[tot].ans);
}
else if(opt==2){
lo++;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);wt[lo].ans=(x2-x1+1)*(y2-y1+1)*si;
tot++;s[tot].x=x2;s[tot].y=y2;s[tot].ans=0;s[tot].val=1;s[tot].num=lo;
tot++;s[tot].x=x1-1;s[tot].y=y1-1;s[tot].ans=0;s[tot].val=2;s[tot].num=lo;
tot++;s[tot].x=x1-1;s[tot].y=y2;s[tot].ans=0;s[tot].val=3;s[tot].num=lo;
tot++;s[tot].x=x2;s[tot].y=y1-1;s[tot].ans=0;s[tot].val=4;s[tot].num=lo;
}
else break;
}
CDQ(1,tot);
for(int i=1;i<=tot;i++) if(s[i].val) wt[s[i].num].cl[s[i].val]=s[i].ans;
for(int i=1;i<=lo;i++) printf("%d\n",wt[i].ans+wt[i].cl[1]+wt[i].cl[2]-wt[i].cl[3]-wt[i].cl[4]);
return 0;
}