zoukankan      html  css  js  c++  java
  • [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;
    }
    

      

  • 相关阅读:
    tensorflow 学习
    join-semi and join-anti
    深入拆解Tomcat_Jetty 笔记
    Set化
    DDD实战-笔记
    高并发系统设计-笔记
    技术管理
    性能调优-笔记
    程序员是如何思考的-笔记
    LeetCode
  • 原文地址:https://www.cnblogs.com/Winniechen/p/9107790.html
Copyright © 2011-2022 走看看