hdu 5919 Sequence II(主席树)

来源:互联网 发布:淘宝开店人工客服电话 编辑:程序博客网 时间:2024/06/05 03:10

Sequence II

Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2177    Accepted Submission(s): 569


Problem Description
Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,,an There are m queries.

In the i-th query, you are given two integers li and ri. Consider the subsequence ali,ali+1,ali+2,,ari.

We can denote the positions(the positions according to the original sequence) where an integer appears first in this subsequence as p(i)1,p(i)2,,p(i)ki (in ascending order, i.e.,p(i)1<p(i)2<<p(i)ki).

Note that ki is the number of different integers in this subsequence. You should output p(i)ki2for the i-th query.
 

Input
In the first line of input, there is an integer T (T2) denoting the number of test cases.

Each test case starts with two integers n (n2×105) and m (m2×105). There are n integers in the next line, which indicate the integers in the sequence(i.e., a1,a2,,an,0ai2×105).

There are two integers li and ri in the following m lines.

However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to li,ri(1lin,1rin). As a result, the problem became more exciting.

We can denote the answers as ans1,ans2,,ansm. Note that for each test case ans0=0.

You can get the correct input li,ri from what you read (we denote them as li,ri)by the following formula:
li=min{(li+ansi1) mod n+1,(ri+ansi1) mod n+1}

ri=max{(li+ansi1) mod n+1,(ri+ansi1) mod n+1}
 

Output
You should output one single line for each test case.

For each test case, output one line “Case #x: p1,p2,,pm”, where x is the case number (starting from 1) and p1,p2,,pm is the answer.
 

Sample Input
25 23 3 1 5 42 24 45 22 5 2 1 22 32 4
 

Sample Output
Case #1: 3 3Case #2: 3 1
Hint

题意:n个数q次查询,每次查询(l,r)表示查询区间[l,r]内所有不同数字第一次出现的下标,输出这些下标中位数,每一组的l和r都跟上一组的答案有关

解:倒着建树即可


#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>#include<map>#include <bits/stdc++.h>using namespace std;const int N = 4e5+100;typedef long long LL;int rt[N], ls[N*100], rs[N*100], sum[N*100];int a[N], b[N], c[N], tot, ans, vis[N];void build(int &o,int l,int r){    o= ++tot,sum[o]=0;    if(l==r) return ;    int mid=(l+r)/2;    build(ls[o],l,mid);    build(rs[o],mid+1,r);    return ;}void update(int &o,int l,int r,int last,int p,int v){    o= ++tot;    ls[o]=ls[last],rs[o]=rs[last];    sum[o]=sum[last]+v;    if(l==r) return ;    int mid=(l+r)/2;    if(p<=mid) update(ls[o],l,mid,ls[last],p,v);    else update(rs[o],mid+1,r,rs[last],p,v);    return ;}void query(int tt,int l,int r,int L,int R){    if(l>=L&&r<=R)    {        ans+=sum[tt];        return;    }    int mid=(l+r)/2;    if(L<=mid) query(ls[tt],l,mid,L,R);    if(R>mid) query(rs[tt],mid+1,r,L,R);    return ;}int query1(int tt,int l,int r,int p){    if(l==r) return l;    int mid=(l+r)/2;    int tmp=(sum[ls[tt]]);    if(p<=tmp) return query1(ls[tt],l,mid,p);    else return query1(rs[tt],mid+1,r,p-tmp);}int main(){    int t, ncase=1;    scanf("%d", &t);    while(t--)    {        int n, q;        scanf("%d %d", &n, &q);        for(int i=1; i<=n; i++) scanf("%d", &a[i]);        memset(vis,0,sizeof(vis));        tot=0;        build(rt[n+1],1,n);        for(int i=n; i>=1; i--)        {            int tmp=0;            if(!vis[a[i]]) update(rt[i],1,n,rt[i+1],i,1);            else update(tmp,1,n,rt[i+1],vis[a[i]],-1),update(rt[i],1,n,tmp,i,1);            vis[a[i]]=i;        }        int ans1=0;        for(int h=1; h<=q; h++)        {            int l, r, li, ri;            scanf("%d %d", &li, &ri);            l=min((ans1+li)%n+1,(ans1+ri)%n+1);            r=max((ans1+li)%n+1,(ans1+ri)%n+1);            ans=0;            query(rt[l],1,n,l,r);            int p=(ans+1)/2;            ans1=query1(rt[l],1,n,p);            c[h]=ans1;        }        for(int h=1; h<=q; h++)        {            if(h==1) printf("Case #%d: %d",ncase++, c[h]);            else printf(" %d",c[h]);        }        printf("\n");    }    return 0;}