zoukankan      html  css  js  c++  java
  • [洛谷P2184]贪婪大陆

    题目大意:有n个点,每次在l~r之间所有点各加上同一种地雷,或询问某一区间内地雷种数。

    解题思路:首先注意是“加上”而不是“覆盖”。

    然后我们用两棵线段树(树状数组),一棵维护某一区间内左端点个数,另一棵维护右端点个数。

    由于每次只加上一个端点,故为单点修改。

    那么如何查询呢?

    如果1~r内有a个左端点,则说明最多有a种地雷,如果1~l-1内有b个右端点,则说明a种地雷中,有b种的右端点没有达到l(否则一定在l-1之后)。

    那么查询出a和b,然后输出a-b即可。

    很明显是区间修改。

    时间复杂度$O(mlog_2 n)$。

    C++ Code:

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #define N 100005
    int n,m,R,ans,d1[N<<2],d2[N<<2];
    inline int readint(){
    	char c=getchar();
    	for(;!isdigit(c);c=getchar());
    	int d=0;
    	for(;isdigit(c);c=getchar())
    	d=(d<<3)+(d<<1)+(c^'0');
    	return d;
    }
    void add1(int l,int r,int o){
    	++d1[o];
    	if(l!=r){
    		int mid=l+r>>1;
    		if(R<=mid)add1(l,mid,o<<1);
    		if(mid<R)add1(mid+1,r,o<<1|1);
    	}
    }
    void add2(int l,int r,int o){
    	++d2[o];
    	if(l!=r){
    		int mid=l+r>>1;
    		if(R<=mid)add2(l,mid,o<<1);
    		if(mid<R)add2(mid+1,r,o<<1|1);
    	}
    }
    void query1(int l,int r,int o){
    	if(r<=R)ans+=d1[o];else{
    		int mid=l+r>>1;
    		query1(l,mid,o<<1);
    		if(mid<R)query1(mid+1,r,o<<1|1);
    	}
    }
    void query2(int l,int r,int o){
    	if(r<=R)ans+=d2[o];else{
    		int mid=l+r>>1;
    		query2(l,mid,o<<1);
    		if(mid<R)query2(mid+1,r,o<<1|1);
    	}
    }
    int main(){
    	n=readint(),m=readint();
    	memset(d1,0,sizeof d1);
    	memset(d2,0,sizeof d2);
    	while(m--){
    		int opt=readint(),l=readint(),r=readint();
    		if(opt==1){
    			R=l;
    			add1(1,n,1);
    			R=r;
    			add2(1,n,1);
    		}else{
    			int Ans=0;
    			ans=0;
    			R=r;
    			query1(1,n,1);
    			Ans+=ans;
    			ans=0;
    			R=l-1;
    			if(R)
    			query2(1,n,1);
    			Ans-=ans;
    			printf("%d
    ",Ans);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    OSI安全体系结构
    PHP 二维数组根据相同的值进行合并
    Java实现 LeetCode 17 电话号码的字母组合
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 16 最接近的三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 15 三数之和
    Java实现 LeetCode 14 最长公共前缀
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8082331.html
Copyright © 2011-2022 走看看