zoukankan      html  css  js  c++  java
  • 洛谷 贪婪大陆--线段树

    问的就是 每次给你区间  l--r,每次覆盖一种不同的颜色,查询l--r有多少种不同的颜色

    这个问题本质是在问区间l--r有多少不同的区间,利用前缀和计算一下,具体看代码

    #include<iostream>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn = 2e5+111;
    typedef long long ll;
    struct Node{
    	ll val,l,r;
    	ll lazy;
    }tree[3][maxn*4];
    
    int push(int id,int node,int be,int en){
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(tree[id][node].lazy){
    		tree[id][l].val += (mid - be + 1)*tree[id][node].lazy;
    		tree[id][r].val += (en - mid)*tree[id][node].lazy;
    		
    		tree[id][l].lazy += tree[id][node].lazy;
    		tree[id][r].lazy += tree[id][node].lazy;
    		tree[id][node].lazy = 0;
    	}
    	return 0;
    }
    int update(int id,int node,int be,int en,int LL,int RR,int val){
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(LL <= be && en <= RR){
    		tree[id][node].val += (en - be + 1)*val;
    		tree[id][node].lazy += val;
    		return 0;
    	}
    	push(id,node,be,en);
    	if(LL <= mid) update(id,l,be,mid,LL,RR,val);
    	if(RR > mid) update(id,r,mid+1,en,LL,RR,val);
    	tree[id][node].val = tree[id][l].val + tree[id][r].val;
    	return 0;
    }
    int ask(int id,int node,int be,int en,int LL,int RR){
    	if(LL == 0 || RR == 0) return 0;
    	int mid = be + en >> 1;
    	int l = node*2;
    	int r = node*2+1;
    	if(LL <= be && en <= RR){
    		return tree[id][node].val;
    	}	
    	push(id,node,be,en);
    	ll a=0,b=0;
    	if(LL <= mid) a = ask(id,l,be,mid,LL,RR);
    	if(RR > mid)  b = ask(id,r,mid+1,en,LL,RR);
    	return a+b; 
    }
    
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=0;i<m;i++){
    		int op;
    		scanf("%d",&op);
    		if(op == 1){//覆盖 
    			int x,y;
    			scanf("%d%d",&x,&y);
    			update(0,1,1,n,y+1,n,1);//前缀 
    			update(1,1,1,n,x,y,1);
    		}
    		else{
    			int x,y;
    			scanf("%d%d",&x,&y);
    			ll a = ask(0,1,1,n,y,y) - ask(0,1,1,n,x,x);
    			a += ask(1,1,1,n,y,y);
    			printf("%lld
    ",a);
    		}
    	}
    	return 0;
    } 
    

      

  • 相关阅读:
    C#与C++中struct和class的小结
    C#中string的小结
    树的一些操作——遍历,前序和中序建立后续
    一个快速、高效的Levenshtein算法实现——代码实现
    整数拆分
    阶乘结果中0的个数
    普莱菲尔密码矩阵生成算法
    CTF密码学总结
    盲文对照表
    实验吧-古典密码
  • 原文地址:https://www.cnblogs.com/lesning/p/13960729.html
Copyright © 2011-2022 走看看