zoukankan      html  css  js  c++  java
  • HDU--5519 Sequence II (主席树)

    题目链接 2016年长春ccpc I 题

    题目大意 :

    给你n(n≤2∗105n≤2∗105)个数,每个数的大小 0<Ai≤2∗10^5   0<Ai≤2∗10^5。

    再给你m(m≤2∗105≤2∗105)个询问。对于每个询问输入l,r,表示Al...ArAl...Ar这个区间我们得到每个数第一次出现的位置下标的排列,

    假设这个区间有k个不同的数,我们得到的排列是p1<p2<p3<...<pkp1<p2<p3<...<pk,叫你求第(k+1)/2这个数是所在的位置是哪个?

    主席树正着插能得到每个区间不同数最后一次出现的位置,反着插的话可以得到每个不同数第一次出现的位置

    然后就是查找区间k值

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 200005
    struct ac{
      int va,l,r;
    }tre[40*maxn];
    int a[maxn],root[maxn],tot,fa[maxn];
    void init(){
       memset(root,0,sizeof(root));
       memset(tre,0,sizeof(tre));
       memset(fa,0,sizeof(fa));
       tot=0;
    }
    void updata(int l,int r,int &x,int y,int z,int va){
       tre[++tot]=tre[y];
       tre[tot].va+=va;
       x=tot;
       if(l==r) return ;
       int mid=(l+r)/2;
       if(z<=mid) updata(l,mid,tre[x].l,tre[y].l,z,va);
       else updata(mid+1,r,tre[x].r,tre[y].r,z,va);
    }
    int query(int l,int r,int x,int k){
       if(l==r) return l;
       int s=tre[tre[x].l].va;
       int mid=(l+r)/2;
       if(k<=s){
          return query(l,mid,tre[x].l,k);
       }
       return query(mid+1,r,tre[x].r,k-s);
    }
    int getsum(int l,int r,int x,int y,int z){
       if(l==x&&y==r) return tre[z].va;
       int mid=(l+r)/2;
       if(y<=mid){
          return getsum(l,mid,x,y,tre[z].l);
       }else if(x>mid){
          return getsum(mid+1,r,x,y,tre[z].r);
       }else{
          return getsum(l,mid,x,mid,tre[z].l)+getsum(mid+1,r,mid+1,y,tre[z].r);
       }
    }
    int main(){
       int t,cnt=1;
       cin>>t;
       while(t--){
          init();
          int n,m;
          cin>>n>>m;
          for(int j=1;j<=n;j++){
             scanf("%d",&a[j]);
          }
          for(int j=n;j>=1;j--){
             if(fa[a[j]]){
                updata(1,n,root[j],root[j+1],fa[a[j]],-1);
                updata(1,n,root[j],root[j],j,1);
             }else{
                updata(1,n,root[j],root[j+1],j,1);
             }
             fa[a[j]]=j;
          }
          int ans=0;
          printf("Case #%d:",cnt++);
          for(int j=0;j<m;j++){
             int x,y,l,r;
             scanf("%d%d",&x,&y);
             x=(x+ans)%n+1;
             y=(y+ans)%n+1;
             l=min(x,y);r=max(x,y);
             int s=getsum(1,n,l,r,root[l]);
             s=(s+1)/2;
             ans=query(1,n,root[l],s);
             printf(" %d",ans);
          }
          printf("
    ");
       }
    }
  • 相关阅读:
    基于应用外壳的架构
    示例代码和环境配置
    获取元素位置信息:getBoundingClientRect
    nodejs学习记录
    网页整理 --- 要换工作了,把这一堆网页先存起来
    删除网页上的广告
    周数的处理
    十六进制
    [例]字体改变,文章位置不变
    haslayout和BFC
  • 原文地址:https://www.cnblogs.com/Dvelpro/p/9775034.html
Copyright © 2011-2022 走看看