• 校门外的树


    https://loj.ac/problem/10115

    题目描述

      有一条路,每次有两种操作,一是在([l,r])间种上树,每次种的树的种类不同,二是询问区间([l,r])中有多少种树。

    思路

      我们考虑对于每次种树,有效的区间信息可以由开头和结尾得到,所以如果我们要求([l,r])之间的树的种类数,我们用(a[i])表示(i)之前(包括(i))有多少个区间开头,我们用(b[i])表示(i)之前(包括(i))有多少个区间结尾,那么对于询问区间([l,r])答案就是在(l)之前的开头数-(r)之前的结尾数,用树状数组维护这个信息即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=5e4+10;
    
    int read()
    {
    	int res=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
    	return res*w;
    }
    
    int a[N],b[N],n;
    int lowbit(int x)
    {
    	return x&-x;
    }
    void add(int c[],int x,int w)
    {
    	while(x<=n)
    	{
    		c[x]+=w;
    		x+=lowbit(x);
    	}
    }
    int query(int c[],int x)
    {
    	int res=0;
    	while(x)
    	{
    		res+=c[x];
    		x-=lowbit(x);
    	}
    	return res;
    }
    int main() 
    {
    	int m;
    	n=read();m=read();
    	while(m--)
    	{
    		int k=read(),l=read(),r=read();
    		if(k==1)
    		{
    			add(a,l,1);
    			add(b,r,1);
    		}
    		else
    			printf("%d
    ",query(a,r)-query(b,l-1));
    	}
    }
    
    
  • 相关阅读:
    NOI2018 退役记
    APIO2018 被屠记
    CTSC2018 被屠记
    SNOI2018 退役记
    O(1) long long a*b%p
    prufer编码
    杜教筛
    GCC卡常
    NOIP2017滚粗记
    UVA 10763 Foreign Exchange
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11755231.html
Copyright © 2020-2023  润新知