• BZOJ2683: 简单题


    题解: cdq分治一下即可 把查询分成四个矩形

    #include <bits/stdc++.h>
    const int MAXN=8e5+10;
    const int NM=5e5+10;
    using namespace std;
    const int inf=1e9;
    typedef struct node{
    	int x,y,id,vul;
    }node;
    node d[MAXN],p[MAXN];int ans[NM];
    int sum[NM],n;
    int get_id(int x){return x&(-x);}
    void add(int x,int vul){
    	for(int i=x;i<=n;i+=get_id(i))sum[i]+=vul;
    }
    int Sum(int x){
    	int ans1=0;
    	for(int i=x;i>0;i-=get_id(i))ans1+=sum[i];
    	return ans1;
    }
    void clear(int x){
    	if(!x)return ;
    	for(int i=x;i<=n;i+=get_id(i))sum[i]=0;
    }
    void merge(int l,int mid,int r){
    	int i=l;int j=mid+1;int cnt=0;
    	//cout<<l<<"++++"<<r<<endl;
    	while(i<=mid&&j<=r){
    		while(i<=mid&&d[i].x<=d[j].x){
    			if(!d[i].id)add(d[i].y,d[i].vul);
    			p[++cnt]=d[i];i++;
    		}
    		if(d[j].id>0)ans[d[j].id]+=Sum(d[j].y);
    		if(d[j].id<0)ans[-1*d[j].id]-=Sum(d[j].y);
    		p[++cnt]=d[j];j++;
    		//cout<<l<<":::"<<r<<i<<" "<<j<<endl;
    	}
    	if(j<=r){
    		for(;j<=r;j++){
    			if(d[j].id>0)ans[d[j].id]+=Sum(d[j].y);
    			if(d[j].id<0)ans[-1*d[j].id]-=Sum(d[j].y);
    			p[++cnt]=d[j];
    		}
    	}
    	//cout<<"sb"<<endl;
    	if(i<=mid){
    		for(;i<=mid;i++)p[++cnt]=d[i];
    	}
    	//cout<<"sb"<<endl;
    	for(int i=1;i<=cnt;i++)d[l+i-1]=p[i],clear(p[i].y);
    }
    void cdq(int l,int r){
    	//cout<<l<<" "<<r<<endl;
    	if(l>=r)return ;
    	int mid=(l+r)>>1;
    	cdq(l,mid);
    	cdq(mid+1,r);
    	merge(l,mid,r);
    	//cout<<l<<" "<<r<<" "<<mid<<endl;
    	//for(int i=l;i<=r;i++)cout<<d[i].x<<"===="<<d[i].y<<" "<<d[i].id<<endl;
    }
    int main(){
    	scanf("%d",&n);
    	int op,x1,x2,y1,y2;int cnt=0,cnt1=0;
    	for(int i=1;;i++){
    		scanf("%d",&op);
    		if(op==3)break;
    		cnt1++;
    		if(op==1)scanf("%d%d%d",&x1,&y1,&y2),d[++cnt].x=x1,d[cnt].y=y1,d[cnt].id=0,d[cnt].vul=y2,ans[i]=inf;
    		else{
    			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);ans[i]=0;
    			d[++cnt].x=x2;d[cnt].y=y2;d[cnt].id=i;
    			d[++cnt].x=x1-1;d[cnt].y=y1-1;d[cnt].id=i;
    			d[++cnt].x=x1-1;d[cnt].y=y2;d[cnt].id=-i;
    			d[++cnt].x=x2;d[cnt].y=y1-1;d[cnt].id=-i;
    		}
    	}
    	cdq(1,cnt);
    	//cout<<cnt1<<endl;
    	for(int i=1;i<=cnt1;i++){
    		if(ans[i]!=inf)printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    

    2683: 简单题

    Time Limit: 50 Sec  Memory Limit: 128 MB
    Submit: 2225  Solved: 916
    [Submit][Status][Discuss]

    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。
    接下来每行一个操作。
     

    Output

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

    Sample Input

    4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3

    Sample Output

    3
    5

    HINT

    1<=N<=500000,操作数不超过200000个,内存限制20M。
    对于100%的数据,操作1中的A不超过2000。
  • 相关阅读:
    .Net 中double相加的困惑
    关于内存资源消耗快的问题
    内存资源消耗快的问题
    跨线程更新窗体
    .Net实现双缓冲
    TypeConverter
    emf文件的导入
    在资源中存放图象与emf文件的显示
    笔记java中nextLine方法没有输入就跳过了
    Silverlight Triggers、Actions 和 Behaviors
  • 原文地址:https://www.cnblogs.com/wang9897/p/9461847.html
Copyright © 2020-2023  润新知