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 }
  • 相关阅读:
    二叉树重建leetcode
    leetcode 字符串
    leetcode first missing positive,覆盖区间
    leetcode 较难题
    Linq分页
    Linq 数据库通用的操作类
    .Net3.5扩展方法实现对象JSON序列化
    js 判断输入内容(主要针对汉字)的字节长度
    div 内table 居中
    Linq增、删、改、查
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/13732853.html
Copyright © 2011-2022 走看看