zoukankan      html  css  js  c++  java
  • 洛谷P1972 [SDOI2009]HH的项链——题解

    题目传送

    核心问题:快速求出各个区间的不同数的个数,数的值域为:[1,1e6]  (即可用O(n)数组存下)。

    在线算法难以快速维护,尝试先对询问处理,采用离线算法。将询问按区间右端点r升序排列,当r确定时,一个数是否对这个询问做过贡献,只需看它在r左面的最右数是否在这个区间内,即用右端点左面的最右数来等效代替了重复且难以处理的数。设一个布尔数组f[n],表示i位置是否为当前r时某个数的最右数。可用树状数组维护其前缀和(好像nlogn的复杂度只能用树状数组,因为题目有点卡常)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 const int N=1e6+5;
     8 
     9 int a[N],n,m,lst[N],tre[N];
    10 
    11 struct node{
    12     int l,r,ord,ans;
    13 }q[N];
    14 
    15 inline int read()
    16 {
    17     int x=0;
    18     char ch=getchar();
    19     while(!isdigit(ch)) 
    20         ch=getchar();
    21     while(isdigit(ch))
    22         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    23     return x;
    24 }
    25 
    26 inline int cmp1(const node &u,const node &v)
    27 {
    28     return u.r<v.r;
    29 }
    30 
    31 inline int cmp2(const node &u,const node &v)
    32 {
    33     return u.ord<v.ord;
    34 }
    35 
    36 inline int lowbit(const int &x)
    37 {
    38     return x&(-x);
    39 }
    40 
    41 inline void insert(int k,int x)
    42 {
    43     for(;k<=n;k+=lowbit(k))
    44         tre[k]+=x;
    45 }
    46 
    47 inline int fin(int k)
    48 {
    49     int ret=0;
    50     for(;k>=1;k-=lowbit(k))
    51         ret+=tre[k];
    52     return ret;
    53 }
    54 
    55 int main()
    56 {
    57     n=read();
    58     for(int i=1;i<=n;++i)
    59         a[i]=read();
    60     m=read();
    61     for(int i=1;i<=m;++i)
    62         q[i].l=read(),q[i].r=read(),q[i].ord=i;
    63     sort(q+1,q+m+1,cmp1);
    64     int k=0;
    65     for(int cnt=1;cnt<=m;++cnt)
    66     {
    67         while(k<q[cnt].r)
    68         {
    69             ++k;
    70             if(lst[a[k]])
    71                 insert(lst[a[k]],-1);
    72             insert(k,1);
    73             lst[a[k]]=k;
    74         }
    75         q[cnt].ans=fin(q[cnt].r)-fin(q[cnt].l-1);
    76     }
    77     sort(q+1,q+m+1,cmp2);
    78     for(int i=1;i<=m;++i)
    79         printf("%d
    ",q[i].ans);
    80     return 0;
    81 }
  • 相关阅读:
    django regroup的相关知识点
    python学习
    python os的一点心得
    python字符串替换的2种有效方法
    python的缩进格式真的不好吗?
    django的哲学很耐人回味
    python 抓取网页的方法
    分享一点python 编码设置的知识
    python apply的一点知识
    今天休息真舒服
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/13732853.html
Copyright © 2011-2022 走看看