• [HEOI2012]采花 BZOJ2743


    分析:

    听说主席树和莫队可以做,前者不想写,后者我不会...

    我们考虑将询问离线,按照左端点排序,之后先处理好从1开始选的答案,之后枚举从1到n,之后依次删除nxt[i],添加nxt[nxt[i]],之后当询问左端点等于i的时候,更新答案。

    附上代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define N 1000005
    int n,m,a[N],vis[N],nxt[N],sum[N];
    int find(int x)
    {
        int ret=0;
        for(int i=x;i;i-=i&-i)ret+=sum[i];
        return ret;
    }
    void fix(int x,int c)
    {
        for(int i=x;i<N;i+=i&-i)sum[i]+=c;
    }
    struct node
    {
        int idx,l,r,ans;
    }q[N];
    bool cmp(const node &a,const node &b){return a.l<b.l;}
    bool cmp1(const node &a,const node &b){return a.idx<b.idx;}
    int main()
    {
        scanf("%d%*d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(vis[a[i]])nxt[vis[a[i]]]=i;
            vis[a[i]]=i;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&q[i].l,&q[i].r);q[i].idx=i;
        }
        sort(q+1,q+m+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(nxt[i])fix(nxt[i],1);
            if(nxt[nxt[i]]) fix(nxt[nxt[i]],-1);
        }
        int h=1;
        for(int i=1;i<=n;i++)
        {
            while(q[h].l==i)q[h].ans=find(q[h].r)-find(i-1),h++;
            if(nxt[i])fix(nxt[i],-1);
            if(nxt[nxt[i]])fix(nxt[nxt[i]],1);
        }
        sort(q+1,q+m+1,cmp1);
        for(int i=1;i<=m;i++)
        {
            printf("%d
    ",q[i].ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Part 29 AngularJS intellisense in visual studio
    Part 28 AngularJS default route
    css动画效果之一
    css
    css.盒子阴影
    css字行标签谁写写
    简单的介绍a标签点击个成
    看css.1的启示。
    css.1
    总结:html
  • 原文地址:https://www.cnblogs.com/Winniechen/p/9107790.html
Copyright © 2020-2023  润新知