zoukankan      html  css  js  c++  java
  • hdu_5919_Sequence II(主席树)

    题目链接:hdu_5919_Sequence II

    题意:

    给你n个数,m个询问,每次问你一个区间中每一种数在区间中第一次出现的位置的中位数,强制在线。

    题解:

    一看就是主席树搞,不过这里要询问第一次出现的位置,有个技巧就是倒着将数插进去,如果有相同的数,就把位置靠后的数的贡献取消掉,这样查询的时候就只需要查询root[l]了,因为root[l]包括了l到n的信息,前面已经只保留了相同数的最前面的位置,所以查询一共有多少种数时直接查询root[l]的l到r就行了。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 using namespace std;
     4 
     5 const int N=2e5+7;
     6 struct node{int l,r,sum;}T[40*N];
     7 
     8 int t,n,m,a[N],pre[N],root[N],tot,ic=1;
     9 
    10 void update(int &x,int y,int pos,int val,int l=1,int r=n)
    11 {
    12     T[++tot]=x?T[x]:T[y],T[tot].sum+=val,x=tot;
    13     if(l==r)return;
    14     int m=l+r>>1;
    15     if(pos<=m)update(T[x].l,T[y].l,pos,val,l,m);
    16     else update(T[x].r,T[y].r,pos,val,m+1,r);
    17 }
    18 
    19 int query(int x,int k,int l=1,int r=n)
    20 {
    21     if(l==r)return l;
    22     int m=l+r>>1;
    23     if(k<=T[T[x].l].sum)return query(T[x].l,k,l,m);
    24     return query(T[x].r,k-T[T[x].l].sum,m+1,r);
    25 }
    26 
    27 int getsum(int x,int L,int R,int l=1,int r=n)
    28 {
    29     if(L<=l&&r<=R)return T[x].sum;
    30     int m=l+r>>1,ans=0;
    31     if(L<=m)ans+=getsum(T[x].l,L,R,l,m);
    32     if(R>m)ans+=getsum(T[x].r,L,R,m+1,r);
    33     return ans;
    34 }
    35 
    36 int main()
    37 {
    38     scanf("%d",&t);
    39     while(t--)
    40     {
    41         printf("Case #%d: ",ic++);
    42         scanf("%d%d",&n,&m);
    43         tot=0;
    44         F(i,1,n)scanf("%d",a+i);
    45         for(int i=n;i>0;i--)
    46         {
    47             if(pre[a[i]])update(root[i],root[i+1],pre[a[i]],-1);
    48             update(root[i],root[i+1],i,1);
    49             pre[a[i]]=i;
    50         }
    51         int ans=0,l,r,sum;
    52         F(i,1,m)
    53         {
    54             scanf("%d%d",&l,&r);
    55             l=(l+ans)%n+1,r=(r+ans)%n+1;
    56             if(l>r)l^=r,r^=l,l^=r;
    57             sum=getsum(root[l],l,r);
    58             printf("%d%c",ans=query(root[l],sum+1>>1)," 
    "[i==m]);
    59         }
    60         while(tot)T[tot].l=T[tot].r=T[tot].sum=0,tot--;
    61         F(i,1,n)root[i]=0,pre[a[i]]=0;
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    求最大公约数和最小公倍数,从文件输入数据,将结果输出到另外一个文件
    在CentOS系统中安装quota来管理磁盘配额
    The implementation details of the built thermal setup
    Task set generation
    利用FPGA加速实现高性能计算
    跨域名上传图片
    这几天基本是混过来的
    jQuery插件之Cookie
    jQuery on()方法
    CActiveForm提示中文化
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5998407.html
Copyright © 2011-2022 走看看