zoukankan      html  css  js  c++  java
  • HDU5919 SequenceⅡ

    从后向前建主席树,以位置为下标建树,然后查询区间出现次数的第k/2大即可。

    复杂度O(nlogn)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=2e5+10;
     4 int num,ans[N],T,pre[N],rt[N],a[N];
     5 struct node
     6 {
     7     int s,l,r;
     8 }t[N*36];
     9 void init()
    10 {
    11     memset(rt,0,sizeof(rt));num=0;
    12     memset(pre,0,sizeof(pre));
    13 }
    14 void change(int &x,int y,int l,int r,int p,int w)
    15 {
    16     x=++num;t[x]=t[y];
    17     if(l==r){t[x].s+=w;return;}
    18     int m=l+r>>1;
    19     if(m<p)change(t[x].r,t[y].r,m+1,r,p,w);
    20     else change(t[x].l,t[y].l,l,m,p,w);
    21     t[x].s=t[t[x].l].s+t[t[x].r].s;
    22 }
    23 int query(int x,int l,int r,int L,int R)
    24 {
    25     if(l==L&&r==R)return t[x].s;
    26     int m=l+r>>1;
    27     if(L>m)return query(t[x].r,m+1,r,L,R);
    28     else if(m>=R)return query(t[x].l,l,m,L,R);
    29     else return query(t[x].l,l,m,L,m)+query(t[x].r,m+1,r,m+1,R);
    30 }
    31 int find(int x,int l,int r,int p)
    32 {
    33     if(l==r)return l;
    34     int m=l+r>>1;
    35     if(t[t[x].l].s>=p)return find(t[x].l,l,m,p);
    36     return find(t[x].r,m+1,r,p-t[t[x].l].s);
    37 }
    38 int main()
    39 {
    40     scanf("%d",&T);int n,m,cnt;
    41     for(int ii=1;ii<=T;++ii)
    42     {
    43         scanf("%d%d",&n,&m);
    44         init();
    45         for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    46         for(int i=n;i;--i)
    47         {
    48             change(rt[i],rt[i+1],1,n,i,1);
    49             if(pre[a[i]])change(rt[i],rt[i],1,n,pre[a[i]],-1);
    50             pre[a[i]]=i;
    51         }ans[0]=0;
    52         for(int i=1;i<=m;++i)
    53         {
    54             int x,y;
    55             scanf("%d%d",&x,&y);
    56             x=(x+ans[i-1])%n+1;
    57             y=(y+ans[i-1])%n+1;
    58             if(x>y)swap(x,y);
    59             int k=query(rt[x],1,n,x,y);
    60             ans[i]=find(rt[x],1,n,(k+1)/2);
    61         }
    62         printf("Case #%d:",ii);
    63         for(int i=1;i<=m;++i)printf(" %d",ans[i]);
    64         puts("");
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    dotnet core 获取 MacAddress 地址方法
    dotnet core 获取 MacAddress 地址方法
    dotnet core 发布只带必要的依赖文件
    dotnet core 发布只带必要的依赖文件
    Developing Universal Windows Apps 开发UWA应用 问答
    Developing Universal Windows Apps 开发UWA应用 问答
    cmd 如何跨驱动器移动文件夹
    cmd 如何跨驱动器移动文件夹
    C++ 驱动开发 error LNK2019
    C++ 驱动开发 error LNK2019
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8485959.html
Copyright © 2011-2022 走看看