您的位置:首页 > 产品设计 > UI/UE

hdu 5919 Sequence II 2016ACM/CCPC长春赛区现场赛J

2016-10-11 20:20 399 查看
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)⌈ki2⌉for
the i-th query.

 

Input

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

Each test case starts with two integers n (n≤2×105)
and m (m≤2×105).
There are n integers in the next line, which indicate the integers in the sequence(i.e., a1,a2,⋯,an,0≤ai≤2×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 l‘i,r‘i(1≤l‘i≤n,1≤r‘i≤n).
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 l‘i,r‘i)by
the following formula:

li=min{(l‘i+ansi−1) mod n+1,(r‘i+ansi−1) mod n+1}

ri=max{(l‘i+ansi−1) mod n+1,(r‘i+ansi−1) 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

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



先写了一个二分位置两个log的。。然后T了。听说现场赛可以过

然后去看了题解,发现只要倒着枚举l加入,每次只将离l最近的第一次出现的各个不同数的位置+1

这样如果询问l,r,那么就直接询问区间和就可以了

然后求k/2。因为倒着加入的,所以可以直接在线段树直接查询值为k/2的那个位置就好,这样就不需要二分那个log了

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
struct tree
{
//int l,r;
int ll,rr;
int s;
}tr[10000001];
int tot;
int rt[2000001],a[2000001];
int n;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9')
{
//if(ch=='-')f=-1;
ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void build(int l,int r)
{
int p=tot;
//tr[p].l=l;
//tr[p].r=r;
if(l!=r)
{
int mid=(l+r)/2;
tot++;
tr[p].ll=tot;
build(l,mid);
tot++;
tr[p].rr=tot;
build(mid+1,r);
tr[p].s=tr[tr[p].ll].s+tr[tr[p].rr].s;
}
else
{
tr[p].ll=0;
tr[p].rr=0;
tr[p].s=0;
}
}
inline int inc(int p,int ll,int rr,int l,int r,int x)
{
if(p==0)
return 0;
if(ll==l&&rr==r)
{
tot++;
// tr[tot].l=l;
// tr[tot].r=r;
tr[tot].s=tr[p].s+x;
return tot;
}
else
{
int mid=(ll+rr)/2;
tot++;
int pp=tot;
//tr[pp].l=tr[p].l;
// tr[pp].r=tr[p].r;
if(l<=mid)
tr[pp].ll=inc(tr[p].ll,ll,mid,l,r,x);
else
tr[pp].ll=tr[p].ll;
if(r>mid)
tr[pp].rr=inc(tr[p].rr,mid+1,rr,l,r,x);
else
tr[pp].rr=tr[p].rr;
tr[pp].s=tr[tr[pp].ll].s+tr[tr[pp].rr].s;
return pp;
}
}
inline int ask(int p2,int p1,int ll,int rr,int l,int r)
{
if(p1==0)
return 0;
if(l<=ll&&rr<=r)
return tr[p2].s-tr[p1].s;
else
{
int mid=(ll+rr)/2;
int sum=0;
if(l<=mid)
sum+=ask(tr[p2].ll,tr[p1].ll,ll,mid,l,r);
if(r>mid)
sum+=ask(tr[p2].rr,tr[p1].rr,mid+1,rr,l,r);
return sum;
}
}
inline int sx(int p,int l,int r,int x)
{
if(l==r)
return l;
int mid=(l+r)/2;
if(tr[tr[p].ll].s>=x)
return sx(tr[p].ll,l,mid,x);
return sx(tr[p].rr,mid+1,r,x-tr[tr[p].ll].s);
}
int la[2000001];
int main()
{
int T,k=0;
//scanf("%d",&T);
T=read();
while(T>0)
{
T--;
k++;
int m;
n=read();
m=read();
// scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++)
a[i]=read();
// scanf("%d",&a[i]);
memset(la,0,sizeof(la));
tot=1;
rt[0]=1;
build(1,n);
for(i=n;i>=1;i--)
{
if(la[a[i]]==0)
{
rt[i]=tot+1;
inc(rt[(i+1)%(n+1)],1,n,i,i,1);
la[a[i]]=i;
}
else
{
int d=tot+1;
inc(rt[(i+1)%(n+1)],1,n,la[a[i]],la[a[i]],-1);
rt[i]=tot+1;
inc(d,1,n,i,i,1);
la[a[i]]=i;
}
}
printf("Case #%d:",k);
int lx,rx,l,r;
int las=0;
for(i=1;i<=m;i++)
{
// scanf("%d%d",&lx,&rx);
lx=read();
rx=read();
l=min((lx+las)%n+1,(rx+las)%n+1);
r=max((lx+las)%n+1,(rx+las)%n+1);
//printf("\n\n%d %d\n\n",l,r);
int sum=ask(rt[l],rt[(r+1)%(n+1)],1,n,l,r);
int dx=(sum+1)/2;
int ll=sx(rt[l],1,n,dx);
printf(" %d",ll);
las=ll;
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  主席树