您的位置:首页 > 其它

BZOJ4066: 简单题

2016-08-12 08:36 141 查看
题目大意:两个操作,单点修改,矩形求和,强制在线,矩阵边长≤50W

强制在线不能用cdq,所以只能上K-DTREE了,然而这题动态加点,所以每插入一定次数就暴力重建一次,这样时间复杂度大概是O(Nsqrt(N))级别的,我也不太清楚

#pragma GCC optimize("O2")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200010
using namespace std;
struct node
{
int v[2],mx[2],mn[2],ch[2],w,sum;
}a
;
int D;
bool cmp(node x,node y)
{
return x.v[D]<y.v[D];
}
void pup(int x)
{
int i,j;
for(i=0;i<2;i++)
{
a[x].mn[i]=a[x].mx[i]=a[x].v[i];
a[x].sum=a[x].w;
}
for(i=0;i<2;i++)
if(a[x].ch[i])
{
a[x].sum+=a[a[x].ch[i]].sum;
for(j=0;j<2;j++)
{
a[x].mn[j]=min(a[x].mn[j],a[a[x].ch[i]].mn[j]);
a[x].mx[j]=max(a[x].mx[j],a[a[x].ch[i]].mx[j]);
}
}
}
int build(int l,int r,int now)
{
int mid=(l+r)>>1;
D=now;
nth_element(a+l,a+mid,a+r+1,cmp);
if(l<mid) a[mid].ch[0]=build(l,mid-1,now^1);
else a[mid].ch[0]=0;
if(r>mid) a[mid].ch[1]=build(mid+1,r,now^1);
else a[mid].ch[1]=0;
int i;
pup(mid);
return mid;
}
int cnt=0,root;
void add(int &k,int x,int now)
{
if(!k){k=x;pup(k);return;}
if(a[x].v[now]<a[k].v[now])
add(a[k].ch[0],x,now^1);
else
add(a[k].ch[1],x,now^1);
pup(k);
}
int check(int k,int x4,int x5,int y4,int y5)
{
if(!k) return 0;
int MN[2]={x4,y4},MX[2]={x5,y5};
if(a[k].mn[0]>=MN[0]&&a[k].mx[0]<=MX[0]&&a[k].mn[1]>=MN[1]&&a[k].mx[1]<=MX[1]) return a[k].sum;
if(a[k].mn[0]>MX[0]||a[k].mx[0]<MN[0]||a[k].mn[1]>MX[1]||a[k].mx[1]<MN[1]) return 0;
int ret=check(a[k].ch[0],x4,x5,y4,y5)+check(a[k].ch[1],x4,x5,y4,y5);
if(a[k].v[0]<=MX[0]&&a[k].v[0]>=MN[0]&&a[k].v[1]<=MX[1]&&a[k].v[1]>=MN[1]) ret+=a[k].w;
return ret;
}
char xB[1<<15],*xS=xB,*xT=xB;
#define getc() (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
inline int read(){
char ch=getc();
int f=1,x=0;
while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getc();}
return x*f;
}
int main()
{
int n;
n=read();
int o,x4,x5,y4,y5;
int LA=0;
while(o=read())
{
if(o==1)
{
cnt++;
a[cnt].v[0]=read();a[cnt].v[1]=read();a[cnt].w=read();
a[cnt].v[0]^=LA;
a[cnt].v[1]^=LA;
a[cnt].w^=LA;
if(cnt%10000==0) root=build(1,cnt,0);
else
{
a[cnt].ch[0]=a[cnt].ch[1]=0;
add(root,cnt,0);
}
}
else if(o==2)
{
x4=read();y4=read();x5=read();y5=read();
x4^=LA;x5^=LA;
y4^=LA;y5^=LA;
LA=check(root,x4,x5,y4,y5);
printf("%d\n",LA);
}
else break;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: