bzoj2743: [HEOI2012]采花

恩这题岂不是裸的莫队?

看下范围上西天。。。

其实和之前一道关于看电影的题很像这里就不赘述了。只不过这里用了树状数组。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n,s[1100000];
int lowbit(int x){return x&-x;}
void change(int x,int k)
{
    while(x<=n)
    {
        s[x]+=k;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int ret=0;
    while(x>0)
    {
        ret+=s[x];
        x-=lowbit(x);
    }
    return ret;
}

int c[1100000];
int first[1100000],next[1100000];
struct query
{
    int l,r,id;
    friend bool operator <(query q1,query q2)
    {
        return q1.l<q2.l;
    }
}q[1100000];int as[1100000];
int main()
{
    int C,m;
    scanf("%d%d%d",&n,&C,&m);
    for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&q[i].l,&q[i].r), q[i].id=i;
    sort(q+1,q+m+1);
    
    memset(first,0,sizeof(first));
    for(int i=n;i>=1;i--)
        next[i]=first[c[i]], first[c[i]]=i;
        
    for(int i=1;i<=C;i++)
        if(first[i]!=0&&next[first[i]]!=0)
            change(next[first[i]],1);
    
    int qt=1;
    for(int i=1;i<=m;i++)
    {
        while(q[qt].l==i)
        {
            as[q[qt].id]=getsum(q[qt].r)-getsum(q[qt].l-1);
            qt++;
        }
        
        if(next[i]!=0)
        {
            change(next[i],-1);
            if(next[next[i]]!=0)change(next[next[i]],1);
        }
    }
    
    for(int i=1;i<=m;i++)printf("%d
",as[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/AKCqhzdy/p/8808119.html