• SPOJ 3267 DQUERY(离线+树状数组)


    传送门

    话说这好像HH的项链啊……

    然后就说一说上次看到的一位大佬很厉害的办法吧

    对于所有$r$相等的询问,需要统计有多少个不同的数,那么对于同一个数字,我们只需要关心它最右边的那一个

    比如$1,2,3,4,1,2$,对于所有$r=5$的询问,我们不用去管第一个$1$因为它一定可以被第五个$1$代替

    同理,对于所有$r=6$的询问,我们也不需要去管第二个$2$

    然后我们可以将所有询问离线,按$r$升序排序

    每一次进行扫描,如果一个数没有出现过,就在树状数组中加入,否则就将它上一次出现的位置的那一个删除,再将它加入

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define N 1000050
     6 #define rint register int
     7 using namespace std;
     8 struct ab{
     9     int l,r,id,ans;
    10 } q[N];
    11 int a[N],f[N],n,m,last[N],r;
    12 inline int read(){
    13     #define num ch-'0'
    14     char ch;bool flag=0;int res;
    15     while(!isdigit(ch=getchar()))
    16     (ch=='-')&&(flag=true);
    17     for(res=num;isdigit(ch=getchar());res=res*10+num);
    18     (flag)&&(res=-res);
    19     #undef num
    20     return res;
    21 }
    22 inline void print(int x) {
    23     if(!x) {
    24         putchar(48);
    25         return;
    26     }
    27     if(x<0) putchar('-'),x=-x;
    28     int l=0,wt[30];
    29     while(x) wt[++l]=x%10,x/=10;
    30     while(l) putchar(wt[l--]+48);
    31 }
    32 inline void add(int x,int y){
    33     while(x<=n)
    34     f[x]+=y,x+=x&(-x);
    35 }
    36 inline int sum(int k){
    37     int s=0;
    38     while(k)
    39     s+=f[k],k-=k&(-k);
    40     return s;
    41 }
    42 inline bool cmp(ab x,ab y){
    43     return x.r<y.r;
    44 }
    45 inline bool cmpp(ab x,ab y){
    46     return x.id<y.id;
    47 }
    48 int main(){
    49     //freopen("testdata.in","r",stdin);
    50     n=read();
    51     for(rint i=1;i<=n;i++) a[i]=read();
    52     m=read();
    53     for(rint i=1;i<=m;i++)
    54     q[i].l=read(),q[i].r=read(),q[i].id=i;
    55     sort(q+1,q+1+m,cmp);
    56     for(rint i=1;i<=m;i++){
    57         while(r<q[i].r){
    58             r++;if(last[a[r]]) add(last[a[r]],-1);
    59             add(r,1),last[a[r]]=r;
    60         }
    61         q[i].ans=sum(q[i].r)-sum(q[i].l-1);
    62     }
    63     sort(q+1,q+1+m,cmpp);
    64     for(rint i=1;i<=m;i++)
    65     print(q[i].ans),putchar(10);
    66     return 0;
    67 }
  • 相关阅读:
    create-react-app 修改 webpack output.publicPath
    洛谷 P1282 多米诺骨牌 (01背包)
    UVa 1627
    UVa 1626
    UVa 11584
    UVa 11400
    UVa 116
    UVa 1347 Tour (dp)
    树形背包小结
    数据流图题目一
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9394057.html
Copyright © 2020-2023  润新知