• luogu1972 HH的项链(树状数组)


    无修改、询问区间种类数的问题可以很容易地用树状数组解决

    我们先给询问按右端点排序,然后推着做,每次让a[i]++,表示i处新增了一个种类

    但是这样会和前面的有重复,我们只要记下每个种类上次在哪里出现过,当这次又出现了,把前面的那次减掉就可以了

    每次处理完之后,就可以计算所有右端点为i的区间的答案,就是这个区间右端点的前缀和减去左端点-1的前缀和

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define ll long long
     4 using namespace std;
     5 const int maxn=5e5+10,maxm=1e6+10;
     6 
     7 inline ll rd(){
     8     ll x=0;char c=getchar();int neg=1;
     9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    11     return x*neg;
    12 }
    13 
    14 int N,M,tr[maxn];
    15 int col[maxn],lst[maxm],ans[maxn];
    16 struct Q{
    17     int l,r,i;
    18 }que[maxn];
    19 
    20 inline int lowbit(int x){return x&(-x);}
    21 inline void add(int x,int y){
    22     for(;x<=N;x+=lowbit(x)) tr[x]+=y;
    23 }
    24 inline int query(int x){
    25     int re=0;for(;x;x-=lowbit(x)) re+=tr[x];return re;
    26 }
    27 
    28 inline bool cmp(Q a,Q b){
    29     return a.r<b.r;
    30 }
    31 
    32 int main(){
    33     int i,j,k;
    34     N=rd();
    35     for(i=1;i<=N;i++) col[i]=rd();
    36     M=rd();
    37     for(i=1;i<=M;i++){
    38         que[i].l=rd(),que[i].r=rd(),que[i].i=i;
    39     }sort(que+1,que+M+1,cmp);
    40     for(i=1,j=1;i<=N;i++){
    41         if(lst[col[i]]) add(lst[col[i]],-1);
    42         add(i,1);lst[col[i]]=i;
    43         for(;que[j].r==i;j++){
    44             ans[que[j].i]=query(i)-query(que[j].l-1);
    45         }
    46     }
    47     for(i=1;i<=M;i++) printf("%d
    ",ans[i]);
    48     return 0;
    49 }
  • 相关阅读:
    不允许修改SQLserver2008r2表中字段的属性问题
    SQL学习笔记 SQL ORDER BY 关键字
    超爱http://www.runoob.com/菜鸟编程
    sqlserver数据类型
    SQL重要命令
    Task--计算器
    改变文本框内容
    Android Studio
    eclipse导入Android项目出现红色感叹号----Solved
    2017-09-09
  • 原文地址:https://www.cnblogs.com/Ressed/p/9681803.html
Copyright © 2020-2023  润新知