Sequence II HDU - 5919

http://acm.hdu.edu.cn/showproblem.php?pid=5919

题意 求给定一个区间 在对前边一个答案进行运算后得到一个新的区间 内有k个不同的数 把它们第一次出现的位置升序排序 问第(k+1)/2个数的下标

因为强制在线 只能用静态主席树 先找出区间内多少不同数 又因为题目问的是按下标排序后 所以就在对应版本的线段树上二分即可 注意数组要开40倍

#include <bits/stdc++.h>
using namespace std;

struct node
{
    int l;
    int r;
    int val;
};

node tree[8000010];
int ary[400010],root[400010],ans[400010],mp[400010];
int n,q,len,num;

int build(int l,int r)
{
    int cur,m;
    cur=num++;
    tree[cur].l=0,tree[cur].r=0,tree[cur].val=0;
    if(l==r) return cur;
    m=(l+r)/2;
    tree[cur].l=build(l,m);
    tree[cur].r=build(m+1,r);
    return cur;
}

int update(int rot,int tar,int val,int l,int r)
{
    int cur,m;
    cur=num++;
    tree[cur]=tree[rot];
    tree[cur].val+=val;
    if(l==r) return cur;
    m=(l+r)/2;
    if(tar<=m) tree[cur].l=update(tree[rot].l,tar,val,l,m);
    else tree[cur].r=update(tree[rot].r,tar,val,m+1,r);
    return cur;
}

int queryI(int rot,int pl,int pr,int l,int r)
{
    int res,m;
    if(pl<=l&&r<=pr) return tree[rot].val;
    res=0,m=(l+r)/2;
    if(pl<=m) res+=queryI(tree[rot].l,pl,pr,l,m);
    if(pr>m) res+=queryI(tree[rot].r,pl,pr,m+1,r);
    return res;
}

int queryII(int rot,int val,int l,int r)
{
    int m;
    if(l==r) return l;
    m=(l+r)/2;
    if(val<=tree[tree[rot].l].val) return queryII(tree[rot].l,val,l,m);
    else return queryII(tree[rot].r,val-tree[tree[rot].l].val,m+1,r);
}

int solve(int rot,int l,int r,int k)
{
    int res;
    if(l>1) res=queryI(rot,1,l-1,1,n);
    else res=0;
    res=queryII(rot,k+res,1,n);
    return res;
}

int main()
{
    int t,cas,i,l,r,k;
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++)
    {
        scanf("%d%d",&n,&q);
        for(i=1;i<=n;i++) scanf("%d",&ary[i]);
        num=0;
        root[n+1]=build(1,n);
        memset(mp,0,sizeof(mp));
        for(i=n;i>=1;i--)
        {
            if(mp[ary[i]]!=0)
            {
                root[i]=update(root[i+1],mp[ary[i]],-1,1,n);
                root[i]=update(root[i],i,1,1,n);
            }
            else
            {
                root[i]=update(root[i+1],i,1,1,n);
            }
            mp[ary[i]]=i;
        }
        for(i=1;i<=q;i++)
        {
            scanf("%d%d",&l,&r);
            l=(l+ans[i-1])%n+1;
            r=(r+ans[i-1])%n+1;
            if(l>r) swap(l,r);
            k=queryI(root[l],l,r,1,n);
            k=(k+1)/2;
            ans[i]=solve(root[l],l,r,k);
        }
        printf("Case #%d:",cas);
        for(i=1;i<=q;i++) printf(" %d",ans[i]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/81572121
今日推荐