# hdu 5919--Sequence II（主席树--求区间不同数个数+区间第k大）

Problem Description
Mr. Frog has an integer sequence of length n, which can be denoted as

Input
In the first line of input, there is an integer T (
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:

Sample Input
2
5 2
3 3 1 5 4
2 2
4 4
5 2
2 5 2 1 2
2 3
2 4

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

Hint

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
typedef long long LL;
const int N=2e5+5;
int a[N],ans[N];
int t[N],tot;
map<int,int>mp;
struct Node
{
int l,r;
int num;
}tr[40*N];
void init()
{
tot=0;
mp.clear();
}
int build(int l,int r)
{
int ii=tot++;
tr[ii].num=0;
if(l<r)
{
int mid=(l+r)>>1;
tr[ii].l=build(l,mid);
tr[ii].r=build(mid+1,r);
}
return ii;
}
int update(int now,int l,int r,int x,int y)
{
int ii=tot++;
tr[ii].num=tr[now].num+y;
tr[ii].l=tr[now].l;
tr[ii].r=tr[now].r;
if(l<r)
{
int mid=(l+r)>>1;
if(x<=mid) tr[ii].l=update(tr[now].l,l,mid,x,y);
else       tr[ii].r=update(tr[now].r,mid+1,r,x,y);
}
return ii;
}
int query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return tr[now].num;
int mid=(l+r)>>1;
int sum=0;
if(mid>=L) sum+=query(tr[now].l,l  ,mid,L,R);
if(mid<R)  sum+=query(tr[now].r,mid+1,r,L,R);
return sum;
}
int finds(int now,int l,int r,int k)
{
if(l==r) return l;
int mid=(l+r)>>1;
if(tr[tr[now].l].num>=k) return finds(tr[now].l,l,mid,k);
else return finds(tr[now].r,mid+1,r,k-tr[tr[now].l].num);
}
int main()
{
int T,Case=1; cin>>T;
while(T--)
{
init();
int n,m; scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
t[n+1]=build(1,n);
for(int i=n;i>=1;i--)
{
if(mp.count(a[i]))
{
int tmp=update(t[i+1],1,n,mp[a[i]],-1);
t[i]=update(tmp,1,n,i,1);
}
else t[i]=update(t[i+1],1,n,i,1);
mp[a[i]]=i;
}
ans[0]=0;
for(int i=1;i<=m;i++)
{
int x,y; scanf("%d%d",&x,&y);
int l=min((x+ans[i-1])%n+1,(y+ans[i-1])%n+1);
int r=max((x+ans[i-1])%n+1,(y+ans[i-1])%n+1);
int k=(query(t[l],1,n,l,r)+1)/2;
ans[i]=finds(t[l],1,n,k);
}
printf("Case #%d:",Case++);
for(int i=1;i<=m;i++) printf(" %d",ans[i]);
puts("");
}
return 0;
}
/**
10 4
1 1 1 1 1 1 1 1 1 1
3 6
6 8
7 10
2 5
*/

posted @ 2017-10-11 17:08  茶飘香~  阅读(147)  评论(0编辑  收藏