校门外的树

Posted fangbozhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了校门外的树相关的知识,希望对你有一定的参考价值。

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));
    }
}

以上是关于校门外的树的主要内容,如果未能解决你的问题,请参考以下文章

P1047 校门外的树

一本通1537校门外的树

Vijos1448校门外的树 题解

校门外的树

练习题 | 校门外的树

校门外的树