• [bzoj2743][HEOI2012]采花(树状数组+离线)


    2743: [HEOI2012]采花

    Time Limit: 15 Sec  Memory Limit: 128 MB
    Submit: 1832  Solved: 954
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    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的花各一朵,公主不采。

    HINT

    【数据范围】

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

    Source

    这道题乍一看很像bzoj1878

    但其实要更难

    (请先参阅bzoj1878  http://www.cnblogs.com/Pumbit-Legion/p/5874133.html)

    上一道题其实是弱化版本

    “求区间内一个及以上的颜色数量”

    而这道题是“两个及以上”

    如何变形是一个问题

    对于每个要加入的元素,可以判断它下一个元素是否存在,存在再加一

    同理,要出去的话,先把因为这个元素而加入的元素删掉,再看看删掉的能不能带来新的元素

    因此,这个问题还能推广到3次,4次等

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 #define LL long long
     6 using namespace std;
     7 typedef struct{
     8     int l,r;
     9     int pos;
    10 }qry;
    11 qry qr[1000010];
    12 int a[1000050];
    13 int now[1001000],next[1000050];
    14 int bit[1000050],n;
    15 int ans[1000050];
    16 int cmp1(const qry a,const qry b){
    17     if(a.l<b.l)return 1;
    18     else if(a.l==b.l)return a.r<b.r;
    19     else return 0;
    20 }
    21 int lb(int x){
    22     return x&(-x);
    23 }
    24 int c1(int x){
    25     while(x<=n){
    26         bit[x]++;
    27         x+=lb(x);
    28     }
    29     return 0;
    30 }
    31 int c2(int x){
    32     while(x<=n){
    33         bit[x]--;
    34         x+=lb(x);
    35     }
    36     return 0;
    37 }
    38 int q(int x){
    39     int ans=0;
    40     while(x){
    41         ans+=bit[x];
    42         x-=lb(x);
    43     }
    44     return ans;
    45 }
    46 int main(){
    47     int m,c;
    48     scanf("%d %d %d",&n,&c,&m);
    49     for(int i=1;i<=n;i++){
    50         scanf("%d",&a[i]);
    51     }
    52     for(int i=n;i>0;i--){
    53         next[i]=now[a[i]];
    54         now[a[i]]=i;
    55     }
    56     for(int i=1;i<=c;i++)if(next[now[i]])c1(next[now[i]]);
    57     for(int i=1;i<=m;i++){
    58         scanf("%d %d",&qr[i].l,&qr[i].r);
    59         qr[i].pos=i;
    60     }
    61     sort(qr+1,qr+m+1,cmp1);
    62     int l=1;
    63     for(int i=1;i<=m;i++){
    64         //?????
    65         while(l<qr[i].l){
    66             if(next[l])c2(next[l]);
    67             if(next[next[l]])c1(next[next[l]]);
    68             l++;
    69         }
    70         ans[qr[i].pos]=q(qr[i].r)-q(qr[i].l-1);
    71     }
    72     for(int i=1;i<=m;i++)printf("%d
    ",ans[i]);
    73     return 0;
    74 }
    View Code

    //ps:后来尹神代码不科学的比我快了将近两秒,于是继续改...

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 #define LL long long
     6 using namespace std;
     7 typedef struct{
     8     int l,r;
     9     int pos;
    10 }qry;
    11 qry qr[1000010];
    12 int a[1000010];
    13 int now[1000010],next[1000010];
    14 int bit[1000010];
    15 int n;
    16 int ans[1000010];
    17 inline int read(){
    18     char ch=getchar();
    19     int sum=0;
    20     while(ch<'0'||ch>'9')ch=getchar();
    21     while(ch<='9'&&ch>='0')sum=sum*10+ch-'0',ch=getchar();
    22     return sum;
    23 }
    24 int cmp1(const qry &a,const qry &b){
    25     return a.l<b.l;
    26 }
    27 inline int lb(int x){
    28     return x&(-x);
    29 }
    30 inline int c1(int x){
    31     while(x<=n){
    32         ++bit[x];
    33         x+=lb(x);
    34     }
    35     return 0;
    36 }
    37 inline int c2(int x){
    38     while(x<=n){
    39         --bit[x];
    40         x+=lb(x);
    41     }
    42     return 0;
    43 }
    44 inline int q(int x){
    45     int ans=0;
    46     while(x){
    47         ans+=bit[x];
    48         x-=lb(x);
    49     }
    50     return ans;
    51 }
    52 int main(){
    53     register int m,c,i,n1;
    54     n=read(),c=read(),m=read();
    55      n1=n;
    56     for(i=1;i<=n1;++i){
    57         a[i]=read();
    58     }
    59     for(i=n1;i>0;--i){
    60         next[i]=now[a[i]];
    61         now[a[i]]=i;
    62     }
    63     for(i=1;i<=c;++i)if(next[now[i]])c1(next[now[i]]);
    64     for(i=1;i<=m;++i){
    65 
    66         qr[i].l=read(),qr[i].r=read();
    67         qr[i].pos=i;
    68     }
    69     sort(qr+1,qr+m+1,cmp1);
    70     register int l=1;
    71     for(i=1;i<=m;++i){
    72         //?????
    73         while(l<qr[i].l){
    74             if(next[l])c2(next[l]);
    75             if(next[next[l]])c1(next[next[l]]);
    76             ++l;
    77         }
    78         ans[qr[i].pos]=q(qr[i].r)-q(qr[i].l-1);
    79     }
    80     for(i=1;i<=m;++i)printf("%d
    ",ans[i]);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    HttpClient 用法
    HttpURLConnection 用法
    Android 真机连接本地PC服务器
    ArrayList VS Vector
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    Implicit super constructor xx() is undefined for default constructor
    layout_gravity
    gravity
    eclipse 建多层包
    RFC 4585 基于实时传输控制协议(RTCP)反馈的扩展RTP(RTP/AVPF)配置文件
  • 原文地址:https://www.cnblogs.com/Pumbit-Legion/p/5874139.html
Copyright © 2020-2023  润新知