码迷,mamicode.com
首页 > 其他好文 > 详细

校门外的树

时间:2019-10-28 21:08:16      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:namespace   ace   owb   main   print   ++   space   答案   之间   

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\n",query(a,r)-query(b,l-1));
    }
}

校门外的树

标签:namespace   ace   owb   main   print   ++   space   答案   之间   

原文地址:https://www.cnblogs.com/fangbozhen/p/11755231.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!