zoukankan      html  css  js  c++  java
  • BZOJ4066: 简单题

    BZOJ4066: 简单题

    Description

    你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

    命令

    参数限制

    内容

    1 x y A

    1<=x,y<=N,A是正整数

    将格子x,y里的数字加上A

    2 x1 y1 x2 y2

    1<=x1<= x2<=N

    1<=y1<= y2<=N

    输出x1 y1 x2 y2这个矩形内的数字和

    3

    终止程序

     

    Input

    输入文件第一行一个正整数N。
    接下来每行一个操作。每条命令除第一个数字之外,均要异或上一次输出的答案last_ans,初始时last_ans=0。

    Output

    对于每个2操作,输出一个对应的答案。

    Sample Input

    4
    1 2 3 3
    2 1 1 3 3
    1 1 1 1
    2 1 1 0 7
    3

    Sample Output

    3
    5

    HINT

    数据规模和约定
    1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。

    题解Here!

    看完题二话不说一个树状数组$+Treap$。
    然后就$MLE$了。。。
    回头看题:怎么只有$20M$???
    这。。。强制在线。。。只好$K-D Tree$。。。
    其实有一道弱化版:

    BZOJ1176: [Balkan2007]Mokia

    但是这道题却只能用$K-D Tree$。。。

    感觉$K-D Tree$要变成替罪羊树了。。。

    还拍平重建。。。

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define MAXN 200010
    #define MAX (1LL<<30)
    #define Alpha 0.75
    using namespace std;
    int n,m;
    int root,size=0,l1,r1,l2,r2;
    int top,recycle[MAXN];
    bool sort_flag=false;
    struct Point{
    	int x,y,z;
    	friend bool operator <(const Point &p,const Point &q){
    		if(sort_flag)return p.y<q.y;
    		return p.x<q.x;
    	}
    }point[MAXN],now;
    struct Tree{
    	Point point;
    	int maxx,maxy,minx,miny,val,sum,size,lson,rson;
    }a[MAXN];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline bool check_inside(int x1,int y1,int x2,int y2){
    	return ((l1<=x1&&x2<=l2)&&(r1<=y1&&y2<=r2));
    }
    inline bool check_outside(int x1,int y1,int x2,int y2){
    	return ((x2<l1||x1>l2)||(y2<r1||y1>r2));
    }
    inline int newnode(const Point &p){
    	int rt;
    	if(top)rt=recycle[top--];
    	else rt=++size;
    	a[rt].point=p;
    	a[rt].maxx=a[rt].minx=p.x;
    	a[rt].maxy=a[rt].miny=p.y;
    	a[rt].val=a[rt].sum=p.z;
    	a[rt].lson=a[rt].rson=0;
    	a[rt].size=1;
    	return rt;
    }
    inline void pushup(int rt){
    	int lson=a[rt].lson,rson=a[rt].rson;
    	a[rt].size=a[lson].size+a[rson].size+1;
    	a[rt].sum=a[lson].sum+a[rson].sum+a[rt].val;
    	a[rt].maxx=max(a[rt].maxx,max(a[lson].maxx,a[rson].maxx));
    	a[rt].maxy=max(a[rt].maxy,max(a[lson].maxy,a[rson].maxy));
    	a[rt].minx=min(a[rt].minx,min(a[lson].minx,a[rson].minx));
    	a[rt].miny=min(a[rt].miny,min(a[lson].miny,a[rson].miny));
    }
    void buildtree(int l,int r,int &rt,int flag){
    	int mid=l+r>>1;
    	sort_flag=flag;
    	nth_element(point+l,point+mid,point+r+1);
    	rt=newnode(point[mid]);
    	if(l<mid)buildtree(l,mid-1,a[rt].lson,flag^1);
    	if(mid<r)buildtree(mid+1,r,a[rt].rson,flag^1);
    	pushup(rt);
    }
    void pia(int rt,int num){
    	if(a[rt].lson)pia(a[rt].lson,num);
    	point[num+a[a[rt].lson].size+1]=a[rt].point;
    	recycle[++top]=rt;
    	if(a[rt].rson)pia(a[rt].rson,num+a[a[rt].lson].size+1);
    }
    inline void check(int &rt,int flag){
    	if(Alpha*a[rt].size<max(a[a[rt].lson].size,a[a[rt].rson].size)){
    		pia(rt,0);
    		buildtree(1,a[rt].size,rt,flag);
    	}
    }
    void insert(int &rt,int flag){
    	if(!rt){
    		rt=newnode(now);
    		return;
    	}
    	sort_flag=flag;
    	if(a[rt].point<now)insert(a[rt].rson,flag^1);
    	else insert(a[rt].lson,flag^1);
    	pushup(rt);
    	check(rt,flag);
    }
    int query(int rt){
    	if(check_inside(a[rt].minx,a[rt].miny,a[rt].maxx,a[rt].maxy))return a[rt].sum;
    	if(check_outside(a[rt].minx,a[rt].miny,a[rt].maxx,a[rt].maxy))return 0;
    	int ans=0;
    	if(check_inside(a[rt].point.x,a[rt].point.y,a[rt].point.x,a[rt].point.y))ans+=a[rt].val;
    	if(a[rt].lson)ans+=query(a[rt].lson);
    	if(a[rt].rson)ans+=query(a[rt].rson);
    	return ans;
    }
    void work(){
    	int f,last=0;
    	while(1){
    		f=read();
    		if(f==3)return;
    		if(f==1){
    			now.x=read()^last;now.y=read()^last;now.z=read()^last;
    			insert(root,0);
    		}
    		else{
    			l1=read()^last;r1=read()^last;l2=read()^last;r2=read()^last;
    			last=query(root);
    			printf("%d
    ",last);
    		}
    	}
    }
    void init(){
    	n=read();
    	a[0].maxx=a[0].maxy=-MAX;
    	a[0].minx=a[0].miny=MAX;
    }
    int main(){
    	init();
    	work();
    	return 0;
    }
    
  • 相关阅读:
    yzoj P2344 斯卡布罗集市 题解
    yzoj P2350 逃离洞穴 题解
    yzoj P2349 取数 题解
    JXOI 2017 颜色 题解
    NOIP 2009 最优贸易 题解
    CH 4302 Interval GCD 题解
    CH4301 Can you answer on these queries III 题解
    Luogu2533[AHOI2012]信号塔
    Luogu3320[SDOI2015]寻宝游戏
    Luogu3187[HNOI2007]最小矩形覆盖
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/10660079.html
Copyright © 2011-2022 走看看