• 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;
    }
    
  • 相关阅读:
    kali更新源
    中国Linux源镜像站大全
    火狐浏览器Firefox上DownThemAll插件
    使用 backdoor 工具注入ShellCode
    动态加载 ShellCode绕过杀软
    渗透测试的本质与沉思
    Payload 实现分离免杀
    XSS跨站攻击靶场-通关笔记
    Web文件上传靶场
    Python 常用外部模块详解
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/10660079.html
Copyright © 2020-2023  润新知