您的位置:首页 > 编程语言

BZOJ2683 简单题 题解&代码

2016-04-08 16:24 337 查看
题意:

给出n*n的棋盘,初始值为0,维护两种操作:

1 x y a 给(x,y)处加a

2 x1 y1 x2 y2 查询(x1,y1)(x2,y2)的矩形内部的和

对每次求和都需要输出答案

思路:

其实我是直接看题解是cdq分治的【捂脸】不敢随意装逼,只是写了一次cdq分治熟悉了一下

插入和查询都是单点操作(查询操作可以修改为4个单点的二维前缀和)

不知所云…有点尴尬,我思考一下再说orz

/**************************************************************
Problem: 2683
User: Rainbow6174
Language: C++
Result: Accepted
Time:8064 ms
Memory:27060 kb
****************************************************************/

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxc = 200005;
int n,c,tot,cnt,x1,y1,x2,y2,a[maxc*4],p[maxc*4],x[maxc*4],y[maxc*4],z[maxc*4],op[maxc*4],ans[maxc],id[maxc*4],ls[maxc*4];
bool cmp(int idx,int idy)
{
if(x[idx]==x[idy])
if(y[idx]==y[idy])return z[idx]<z[idy];
else return y[idx]<y[idy];
return x[idx]<x[idy];
}
int lowbit(int x)
{
return x&(-x);
}
void insert(int x,int l)
{
for(int i = x; i < maxc*4; i+=lowbit(i))
a[i]+=l;
}
int getsum(int x)
{
int ret = 0;
for(int i = x; i > 0; i-=lowbit(i))
ret+=a[i];
return ret;
}
void cdq(int l,int r)
{
if(l==r)return;
//cout<<l<<' '<<r<<endl;
int mid=(l+r)/2;
for(int i = l; i <= r; i++)
if(z[p[i]]==1){
if(p[i]<=mid) insert(y[p[i]],op[p[i]]);
}
else if(p[i]>mid){
ans[id[p[i]]] += op[p[i]]*getsum(y[p[i]]);
}
for(int i = l; i <= r; i++)
if(z[p[i]]==1 && p[i]<=mid) insert(y[p[i]],-op[p[i]]);
int l1=l,l2=mid+1;
for(int i = l; i <= r; i++)
if(p[i]<=mid) ls[l1++] = p[i];
else ls[l2++] = p[i];
for(int i = l; i <= r; i++) p[i] = ls[i];
cdq(l,mid);
cdq(mid+1,r);
}
int main(void)
{
scanf("%d",&n);
while(scanf("%d",&c) && c!=3)
{
p[++tot]=tot;z[tot]=c;
if(c==1)scanf("%d%d%d",&x[tot],&y[tot],&op[tot]);
else
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x[tot]=x1-1;y[tot]=y1-1;op[tot]=1;id[tot]=++cnt;
p[++tot]=tot;z[tot]=c;
x[tot]=x1-1;y[tot]=y2;op[tot]=-1;id[tot]=cnt;
p[++tot]=tot;z[tot]=c;
x[tot]=x2;y[tot]=y1-1;op[tot]=-1;id[tot]=cnt;
p[++tot]=tot;z[tot]=c;
x[tot]=x2;y[tot]=y2;op[tot]=1;id[tot]=cnt;
}
}
sort(p+1,p+1+tot,cmp);
//for(int i = 1; i <= tot; i++)
//cout<<p[i]<<' '<<id[p[i]]<<' '<<z[p[i]]<<' '<<op[p[i]]<<' '<<x[p[i]]<<' '<<y[p[i]]<<' '<<getsum(y[i])<<endl;
cdq(1,tot);
for(int i = 1; i <= cnt; i++)printf("%d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: