• cogs 1619. [HEOI2012]采花 AC


    1619. [HEOI2012]采花

    ★★☆   输入文件:1flower.in   输出文件:1flower.out   简单对比
    时间限制:5 s   内存限制:128 MB

    【题目描述】

    萧薰儿是国的公主,平时的一大爱好是采花。
    今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花。花园足够大,容纳n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公主采花。公主每次采花后会统计采到的花的颜色数,颜色数越多她会越高兴!同时,她有一癖好,她不允许最后自己采到的花中,某一颜色的花只有一朵。为此,公主每采一朵花,要么此前已采到此颜色的花,要么有相当正确的直觉告诉她,她必能再次采到此颜色的花。由于时间关系,公主只能走过花园连续的一段进行采花,便让女仆福涵洁安排行程。福涵洁综合各种因素拟定了m个行程,然后一一向你询问公主能采到多少朵花(她知道你是编程高手,定能快速给出答案!),最后会选择令公主最高兴的行程(为了拿到更多奖金!)。

    【输入格式】


     第一行四个空格隔开的整数nc以及m接下来一行n个空格隔开的整数,每个数在[1, c]间,第i个数表示第i朵花的颜色。接下来m行每行两个空格隔开的整数lrl r),表示女仆安排的行程为公主经过第l到第r朵花进行采花。

    【输出格式】

     
    m行,每行一个整数,第i个数表示公主在女仆的第i个行程中能采到的花的颜色数。

    【样例输入】

    5  3 5
      1  2 2 3 1
      1  5
      1  2
      2  2
      2  3
      3  5
      

    【样例输出】

    2 
      0 0 1 0 
      【样例说明】
      询问[1, 5]:公主采颜色为1和2的花,由于颜色3的花只有一朵,公主不采;询问[1, 2]:颜色1和颜色2的花均只有一朵,公主不采;
      询问[2, 2]:颜色2的花只有一朵,公主不采;
      询问[2, 3]:由于颜色2的花有两朵,公主采颜色2的花;
      询问[3, 5]:颜色1、2、3的花各一朵,公主不采。
      

    【提示】


    【数据范围】

    对于100%的数据,1 ≤ n ≤    10^6,c ≤ n,m ≤10^6。

    考试时20分代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<string>
     7  
     8 using namespace std;
     9 const int N=1000010;
    10  
    11 int a[N];
    12 int b[N];
    13  
    14 inline int read()
    15 {
    16     int x=0,f=1;
    17     char c=getchar();
    18     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    19     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    20     return x*f;
    21 }
    22  
    23 int main()
    24 {
    25     freopen("1flower.in","r",stdin);
    26     freopen("1flower.out","w",stdout);
    27     int n=read();
    28     int m=read();
    29     int k=read();
    30     for(int i=1;i<=n;i++)
    31         a[i]=read();
    32     for(int i=1;i<=k;i++)
    33     {
    34         int u=read();
    35         int v=read();
    36         int Answer=0;
    37         if(u==v){printf("0
    ");continue ;}
    38         memset(b,0,sizeof(b));
    39         int maxn=-1;
    40         
    41         for(int j=u;j<=v;j++)
    42         {
    43             b[a[j]]++;
    44             maxn=max(maxn,a[j]);
    45         }
    46         
    47         for(int j=1;j<=maxn;j++)
    48             if(b[j]>=2)
    49                 Answer++;
    50                 
    51         printf("%d
    ",Answer);
    52     }
    53     
    54     return 0;
    55 }
    56  

     显然,这是一道莫队题,然而莫队在cogs上只得70分:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
     
    using namespace std;
    const int N=2000010;
    
    int a[N],number[N],answer[N],pos[N];
    int n,col,m,base,ans;
    struct node{
        int l,r,id;
    }E[N];
    
    inline int read()
    {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
        return x*f;
    }
    
    inline bool cmp(node a,node b)
    {
        if(pos[a.l]==pos[b.l])
            return a.r<b.r;
        else
            return a.l<b.l;
    }
    
    void add(int x)
    {
        number[x]++;
        if(number[x]==2)
            ans++;
    }
    
    void dale(int x)
    {
        number[x]--;
        if(number[x]==1)
            ans--;
    }
    
    inline void modui()
    {
        int ll=1,rr=0;
        for(int i=1;i<=m;i++)
        {
            for(;E[i].l<ll;ll--)add(a[ll-1]);
            for(;E[i].l>ll;ll++)dale(a[ll]);
            for(;E[i].r<rr;rr--)dale(a[rr]);
            for(;E[i].r>rr;rr++)add(a[rr+1]);
            answer[E[i].id]=ans;
        }
    }
    
    int main()
    {
        freopen("1flower.in","r",stdin);
        freopen("1flower.out","w",stdout);
        n=read(),col=read(),m=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        for(int i=1;i<=m;i++)
            E[i].l=read(),
            E[i].r=read(),
            E[i].id=i;
        base=sqrt(n);
        for(int i=1;i<=n;i++)
            pos[i]=(i-1)/base+1;
        sort(E+1,E+m+1,cmp);
        modui();
        for(int i=1;i<=m;i++)
            printf("%d
    ",answer[i]);
        return 0;
    }
    /*
    5  3  5
    1  2  2  3  1
    1  5
    1  2
    2  2
    2  3
    3  5
    2
    0
    0
    1
    0
    */

    莫队+几个inline就可以过的:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
     
    using namespace std;
    const int N=2000010;
     
    int a[N],number[N],answer[N],pos[N];
    int n,col,m,base,ans;
    struct node{
        int l,r,id;
    }E[N];
     
    inline int read()
    {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
        return x*f;
    }
     
    inline bool cmp(node a,node b)
    {
        if(pos[a.l]==pos[b.l])
            return a.r<b.r;
        else
            return a.l<b.l;
    }
     
    inline void add(int x)
    {
        number[x]++;
        if(number[x]==2)
            ans++;
    }
     
    inline void dale(int x)
    {
        number[x]--;
        if(number[x]==1)
            ans--;
    }
     
    inline void modui()
    {
        int ll=1,rr=0;
        for(int i=1;i<=m;i++)
        {
            for(;E[i].l<ll;--ll)add(a[ll-1]);
            for(;E[i].l>ll;++ll)dale(a[ll]);
            for(;E[i].r<rr;--rr)dale(a[rr]);
            for(;E[i].r>rr;++rr)add(a[rr+1]);
            answer[E[i].id]=ans;
        }
    }
     
    int main()
    {
        freopen("1flower.in","r",stdin);
        freopen("1flower.out","w",stdout);
        n=read(),col=read(),m=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        base=sqrt(n);
        for(int i=1;i<=n;i++)
            pos[i]=(i-1)/base+1;
            
        for(int i=1;i<=m;i++)
            E[i].l=read(),
            E[i].r=read(),
            E[i].id=i;
        sort(E+1,E+m+1,cmp);
        modui();
        for(int i=1;i<=m;i++)
            printf("%d
    ",answer[i]);
        return 0;
    }

    然而对于这个树状数组我并没有看懂:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <list>
    #include <cmath>
    using namespace std;
    #define F1 "1flower.in"
    #define F2 "1flower.out"
    #define MAXN 1000002
    int pre[MAXN];
    int last[MAXN];
    int data[MAXN];
    int cnt[MAXN];
    int ans[MAXN];
    struct que
    {
        int l, r;
        int id;
    }ques[MAXN];
    #define Q(i) ques[i]
    bool cmp(const que &a, const que &b)
    {
       return a.r < b.r;
    }
    int n, c, m;
    void add(int x, int v)
    {
        for(int i = x; i <= n; i += i&-i)
            cnt[i] += v;
    }
    int get_s(int x)
    {
        int s = 0;
        for(int i = x; i > 0; i -= i&-i)
            s += cnt[i];
        return s;
    }
    int main()
    {
        freopen(F1, "r", stdin);
        freopen(F2, "w", stdout);
        scanf("%d %d %d", &n, &c, &m);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", data+i);
            pre[i] = last[data[i]];
            last[data[i]] = i;
        }
        for(int i =  0; i < m; i++)
        {
            que &q = ques[i];
            scanf("%d %d", &q.l, &q.r);
            q.id = i;
        }
        sort(ques, ques+m, cmp);
        int t = 0;
        for(int i = 1; i <= n; i++)
        {
            if(pre[i])
            {
                add(pre[i]+1, -1);
                add(pre[pre[i]]+1, 1);
            }
            while(i == ques[t].r)
            {
                ans[ques[t].id] = get_s(ques[t].l);
                t++;
            }
        }
        for(int i = 0; i < m; i++)
            printf("%d ", ans[i]);
        return 0;
    }

     然而树状数组<1000;莫队4000++

  • 相关阅读:
    FRR and VFR
    MEC in 5G networks
    KNI
    SGX KMRA
    5G E2E issues
    物理层无线信道的特征
    PTP 时钟
    Ransim go through
    网页title闪动JavaScript实现消息提醒
    敏感词库
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/6910147.html
Copyright © 2020-2023  润新知