BZOJ 2743 采花

BIT+离线,和上题类似。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000050
using namespace std;
int n,m,c,a[maxn],val[maxn],t[maxn],nxt[maxn],regis[maxn],ans[maxn],cnt[maxn];
struct seg
{
    int l,r,id;
}s[maxn];
bool cmp(seg x,seg y)
{
    return x.l<y.l;
}
int lowbit(int x) {return (x&(-x));}
int ask(int x)
{
    int ret=0;
    for (int i=x;i>=1;i-=lowbit(i))
        ret+=t[i];
    return ret;
}
void modify(int x,int val)
{
    for (int i=x;i<=n+1;i+=lowbit(i))
        t[i]+=val;
}
int main()
{
    scanf("%d%d%d",&n,&c,&m);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=n;i>=1;i--)
    {
        if (!regis[a[i]]) nxt[i]=n+1;
        else nxt[i]=regis[a[i]];
        regis[a[i]]=i;
    }
    nxt[n+1]=n+1;
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
        s[i].id=i;
    }
    sort(s+1,s+m+1,cmp);
    for (int i=1;i<=n;i++)
    {
        cnt[a[i]]++;
        if (cnt[a[i]]==2) val[i]=val[i-1]+1;
        else val[i]=val[i-1];
    }
    int j=1;
    for (int i=1;i<=n;i++)
    {
        for (;j<=m;j++)
        {
            if (s[j].l!=i) break;
            ans[s[j].id]=val[s[j].r]+ask(s[j].r);
        }
        modify(nxt[i],-1);modify(nxt[nxt[i]],1);
    }
    for (int i=1;i<=m;i++) printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/5985828.html