cdq分治——bzoj1176: [Balkan2007]Mokia/bzoj2683: 简单题
http://hzwer.com/6002.html
网上题解么,代码全是一个样的,思路么,全都时很简单的讲讲;
唉;
这题目太明显了呀
i
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Ll long long
using namespace std;
struct cs{int x,y,v,num;bool k;}a[200005],c[200005];
struct toans{int to,k,v;}f[200005];
int F[2000005];
int ans[10005],top;
int n,x,y,z,v,m,xx,yy;
bool cmp2(cs a,cs b){return a.y<b.y;}
void init(int i,int v){for(;i<=m;i+=i&-i)F[i]+=v;}
void cle(int i){for(;i<=m;i+=i&-i)F[i]=0;}
int outit(int i){
int ans=0;
for(;i;i-=i&-i)ans+=F[i];
return ans;
}
void cdq(int l,int r){
if(l==r)return;
int mid=l+r>>1;
cdq(l,mid);
for(int i=l;i<=r;i++)c[i]=a[i];
sort(c+l,c+mid+1,cmp2);
sort(c+mid+1,c+r+1,cmp2);
int k=l-1;
for(int i=mid+1;i<=r;i++)
if(!c[i].k){
while(k<mid&&c[k+1].y<=c[i].y)
if(c[++k].k)
init(c[k].x,c[k].v);
f[c[i].num].v+=outit(c[i].x);
}
for(int i=l;i<=mid;i++)if(c[i].k)cle(c[i].x);
cdq(mid+1,r);
}
int main()
{
scanf("%d%d",&m,&m);
while(1){
scanf("%d",&z);
if(z==3)break;
if(z==1){n++;scanf("%d%d%d",&a[n].x,&a[n].y,&a[n].v);a[n].k=1;}
if(z==2){
scanf("%d%d%d%d",&x,&y,&xx,&yy);
top++;
f[++n].to=top;f[n].k= 1;a[n].x=xx ,a[n].y=yy ;
f[++n].to=top;f[n].k= 1;a[n].x=x-1 ,a[n].y=y-1 ;
f[++n].to=top;f[n].k=-1;a[n].x=xx ,a[n].y=y-1 ;
f[++n].to=top;f[n].k=-1;a[n].x=x-1 ,a[n].y=yy ;
}
}
for(int i=1;i<=n;i++)a[i].num=i;
cdq(1,n);
for(int i=1;i<=n;i++)if(!a[i].k)ans[f[i].to]+=f[i].k*f[i].v;
for(int i=1;i<=top;i++)printf("%d\n",ans[i]);
}
说来惭愧,矩形前缀和打错了,调了1h
双倍经验,爽
2683
:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Ll long long
using namespace std;
struct cs{int x,y,v,num;bool k;}a[1000005],c[1000005];
struct toans{int to,k,v;}f[1000005];
int F[1000005];
int ans[1000005],top;
int n,x,y,z,v,m,xx,yy;
bool cmp2(cs a,cs b){return a.y<b.y;}
void init(int i,int v){for(;i<=m;i+=i&-i)F[i]+=v;}
void cle(int i){for(;i<=m;i+=i&-i)F[i]=0;}
int outit(int i){
int ans=0;
for(;i;i-=i&-i)ans+=F[i];
return ans;
}
void cdq(int l,int r){
if(l==r)return;
int mid=l+r>>1;
cdq(l,mid);
for(int i=l;i<=r;i++)c[i]=a[i];
sort(c+l,c+mid+1,cmp2);
sort(c+mid+1,c+r+1,cmp2);
int k=l-1;
for(int i=mid+1;i<=r;i++)
if(!c[i].k){
while(k<mid&&c[k+1].y<=c[i].y)
if(c[++k].k)
init(c[k].x,c[k].v);
f[c[i].num].v+=outit(c[i].x);
}
for(int i=l;i<=mid;i++)if(c[i].k)cle(c[i].x);
cdq(mid+1,r);
}
int main()
{
scanf("%d",&m);
while(1){
scanf("%d",&z);
if(z==3)break;
if(z==1){n++;scanf("%d%d%d",&a[n].x,&a[n].y,&a[n].v);a[n].k=1;}
if(z==2){
scanf("%d%d%d%d",&x,&y,&xx,&yy);
top++;
f[++n].to=top;f[n].k= 1;a[n].x=xx ,a[n].y=yy ;
f[++n].to=top;f[n].k= 1;a[n].x=x-1 ,a[n].y=y-1 ;
f[++n].to=top;f[n].k=-1;a[n].x=xx ,a[n].y=y-1 ;
f[++n].to=top;f[n].k=-1;a[n].x=x-1 ,a[n].y=yy ;
}
}
for(int i=1;i<=n;i++)a[i].num=i;
cdq(1,n);
for(int i=1;i<=n;i++)if(!a[i].k)ans[f[i].to]+=f[i].k*f[i].v;
for(int i=1;i<=top;i++)printf("%d\n",ans[i]);
}