注:本系列只为整理、保存比赛模板用,并非代码均为自己所写。会给出原代码的链接。
题号:HDU5919
题意:A[1..N],m个询问,每次问[l,r]中所有数的第一次出现的位置的中位数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int tot,root[200010*40];
struct node{
int l,r,s;
}t[200010*40];
void update(int &x,int y,int l,int r,int pos,int c){
t[x=++tot]=t[y];t[x].s+=c;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)update(t[x].l,t[y].l,l,mid,pos,c);
else update(t[x].r,t[y].r,mid+1,r,pos,c);
}
int query(int rt,int l,int r,int nl,int nr){
if(nl<=l&&r<=nr)return t[rt].s;
int mid=(l+r)>>1,ret=0;
if(nl<=mid)ret+=query(t[rt].l,l,mid,nl,nr);
if(nr>mid)ret+=query(t[rt].r,mid+1,r,nl,nr);
return ret;
}
int kth(int rt,int l,int r,int k){
if(l==r)return l;
int mid=(l+r)>>1,s=t[t[rt].l].s;
if(s>=k)return kth(t[rt].l,l,mid,k);
else return kth(t[rt].r,mid+1,r,k-s);
}
int ans,n,a[200010],m;
int pos[200010];
int main(){
int T;
cin>>T;
for(int cases=1;cases<=T;cases++){
memset(root,0,sizeof(root));
memset(pos,0,sizeof(pos));
tot=ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=n;i>=0;i--){
if(!pos[a[i]]){
update(root[i],root[i+1],1,n,i,1);
pos[a[i]]=i;
}
else{
update(root[i],root[i+1],1,n,i,1);
update(root[i],root[i],1,n,pos[a[i]],-1);
pos[a[i]]=i;
}
}
printf("Case #%d:",cases);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
l=(l+ans)%n+1,r=(r+ans)%n+1;
if(l>r)swap(l,r);
int num=query(root[l],1,n,l,r);
ans=kth(root[l],1,n,(num+1)/2);
printf(" %d",ans);
}
puts("");
}
return 0;
}
/*
2
5 2
3 3 1 5 4
2 2
4 4
5 2
2 5 2 1 2
2 3
2 4
*/