• BZOJ1878 [SDOI2009]HH的项链


    NOIP之前写过这题,先用的分块。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=50005;
     4 int t[N+10],a[N+10];
     5 int v[1000005];
     6 int sum=0;
     7 void add(int x)
     8 {
     9     v[x]++;
    10     if(v[x]==1)sum++;
    11 }
    12 void del(int x)
    13 {
    14     v[x]--;
    15     if(v[x]==0)sum--;
    16 }
    17 int sq;
    18 struct node
    19 {
    20     int l,r,id;
    21     bool operator <(const node &b)const
    22     {
    23         if((l/sq)==(b.l/sq))return r<b.r;
    24         return l<b.l;
    25     }
    26 }p[200005];
    27 int ans[200005];
    28 int main()
    29 {
    30     int n;scanf("%d",&n);
    31     sq=sqrt((double)n);    
    32     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    33     int m;
    34     scanf("%d",&m);
    35     for(int i=1;i<=m;++i)
    36     {
    37         scanf("%d%d",&p[i].l,&p[i].r);
    38         p[i].id=i;
    39     }
    40     sort(p+1,p+1+m);
    41     int l=0,r=0;
    42     for(int i=1;i<=m;++i)
    43     {
    44         while(r>p[i].r)del(a[r--]);
    45         while(r<p[i].r)add(a[++r]);
    46         while(l<p[i].l)del(a[l++]);
    47         while(l>p[i].l)add(a[--l]);
    48         ans[p[i].id]=sum;
    49     }
    50     for(int i=1;i<=m;++i)printf("%d
    ",ans[i]);
    51     return 0;
    52 }

    又采用了树状数组,离线按右端点排序,只关心最后一个出现的位置,如果有更新的则将原来的-1将新的位置+1

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=50005;
     4 int t[N+10],a[N+10],b[N+10];
     5 int v[N+10];
     6 int lowbit(int x){
     7     return x&(-x);
     8 }
     9 void add(int x,int y)
    10 {
    11     for(;x<=N;x+=lowbit(x))t[x]+=y;
    12 }
    13 int query(int x)
    14 {
    15     int ans=0;for(;x;x-=lowbit(x))ans+=t[x];return ans;
    16 }
    17 struct node
    18 {
    19     int l,r,id;
    20     bool operator <(const node &b)const
    21     {
    22         if(r==b.r)return l<b.l;
    23         return r<b.r;
    24     }
    25 }p[200005];
    26 int ans[200005];
    27 int main()
    28 {
    29     int n;
    30     scanf("%d",&n);
    31     for(int i=1;i<=n;++i){scanf("%d",&a[i]);b[i]=a[i];}
    32     sort(b+1,b+1+n);
    33     for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+n,a[i])-b;
    34     int m;
    35     scanf("%d",&m);
    36     for(int i=1;i<=m;++i)
    37     {
    38         scanf("%d%d",&p[i].l,&p[i].r);
    39         p[i].id=i;
    40     }
    41     sort(p+1,p+1+m);
    42     int pos=1;
    43     for(int i=1;i<=m;++i)
    44     {
    45         while(pos<=p[i].r)
    46         {
    47             if(v[a[pos]])add(v[a[pos]],-1);
    48             v[a[pos]]=pos;add(v[a[pos]],1);pos++;
    49         }
    50         ans[p[i].id]=query(p[i].r)-query(p[i].l-1);
    51     }
    52     for(int i=1;i<=m;++i)printf("%d
    ",ans[i]);
    53     return 0;
    54 }

    现在我又学了主席树,我们只要对于last(上一次的位置)建主席树,然后查询0~l-1这个区间出现的个数即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1e6+10;
     4 struct node
     5 {
     6     int l,r,s;
     7 }t[N<<2];
     8 int n,m,cnt,last[N],pos[N],rt[N];
     9 void change(int &x,int l,int r,int pos)
    10 {
    11     t[++cnt]=t[x];x=cnt;
    12     if(l==r){t[x].s++;return;}
    13     int mid=l+r>>1;
    14     if(pos<=mid)change(t[x].l,l,mid,pos);
    15     else change(t[x].r,mid+1,r,pos);
    16     t[x].s=t[t[x].l].s+t[t[x].r].s;
    17     return;
    18 }
    19 int query(int x,int y,int l,int r,int L,int R)
    20 {
    21     if(l==L&&r==R)return t[y].s-t[x].s;
    22     int mid=l+r>>1;
    23     if(mid>=R)return query(t[x].l,t[y].l,l,mid,L,R);
    24     else if(mid<L)return query(t[x].r,t[y].r,mid+1,r,L,R);
    25     return query(t[x].l,t[y].l,l,mid,L,mid)+query(t[x].r,t[y].r,mid+1,r,mid+1,R);
    26 }
    27 int main()
    28 {
    29     scanf("%d",&n);int x,l,r;
    30     for(int i=1;i<=n;++i)
    31     {
    32         scanf("%d",&x);
    33         last[i]=pos[x];
    34         pos[x]=i;
    35     }
    36     for(int i=1;i<=n;++i)rt[i]=rt[i-1],change(rt[i],0,n,last[i]);
    37     scanf("%d",&m);
    38     for(int i=1;i<=m;++i)
    39     {
    40         scanf("%d%d",&l,&r);
    41         printf("%d
    ",query(rt[l-1],rt[r],0,n,0,l-1));
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    STM32Cube IDE配置串口发送与接收
    STM32CubeIDE Debug Configurations
    STM32CubeMX FreeRTOS定时器的使用
    单片机处理串口逗号分隔符命令
    自定义任务状态来操作FreeRTOS任务的挂起,恢复,删除
    Halcon WPF C#采集图像区域灰度值
    STM32CubeMX FreeRTOS no definition for "osThreadGetState" 解决办法
    Hyper-V应用
    AutoFixture 数据对象生成器
    visual studio的XAML无法热更新
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8337339.html
Copyright © 2020-2023  润新知