HDU 5919 Sequence II(可持久化线段树)
【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=5919
【题目大意】
给出一个数列,每次查询数列中,区间非重元素的下标的中位数。查询操作强制在线。
【题解】
因为查询的是下标,因此,我们直接在下标操作表示这里有没有数字,然后查询k大数即可,非重元素即需要在区间每个数第一次出现的地方+1,然后对处理完的区间进行查询即可,考虑到查询强制在线,不能扫描线,因此只能建立可持久化线段树,线段树的第i个版本表示第i个位置往后的每个元素第一次出现的位置,那么查询区间【L,R】,就是查询第L个版本的线段树第k大数,然后对于k的计算,我们只要在第L个版本的线段树上查询区间【L,R】中的非重元素个数,即线段树求和,之后除2上取整即可。
【代码】
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200010;
int n,m,i,x,y,z,ans;
int l[N*40],r[N*40],v[N*40],tot,root[N],a[N],pre[N];
void read(int&a){
char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
}
int build(int a,int b){
int x=++tot; v[x]=0;
if(a==b)return x;
int mid=(a+b)>>1;
return l[x]=build(a,mid),r[x]=build(mid+1,b),x;
}
int change(int x,int a,int b,int c,int p){
int y=++tot;v[y]=v[x]+p;
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid)l[y]=change(l[x],a,mid,c,p),r[y]=r[x];
else l[y]=l[x],r[y]=change(r[x],mid+1,b,c,p);
return y;
}
int query(int x,int a,int b,int L,int R){
if(L<=a&&b<=R)return v[x];
int mid=(a+b)/2,res=0;
if(L<=mid)res+=query(l[x],a,mid,L,R);
if(R>mid)res+=query(r[x],mid+1,b,L,R);
return res;
}
int getans(int x,int a,int b,int k){
if(a==b)return a;
int mid=(a+b)>>1;
if(v[l[x]]>=k)return getans(l[x],a,mid,k);
else return getans(r[x],mid+1,b,k-v[l[x]]);
}int T,Cas=0;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);tot=0;
memset(pre,-1,sizeof(pre));
for(int i=1;i<=n;i++)read(a[i]);
root[n+1]=build(1,n);
for(int i=n;i;i--){
if(pre[a[i]]==-1)root[i]=change(root[i+1],1,n,i,1);
else{
int tmp=change(root[i+1],1,n,pre[a[i]],-1);
root[i]=change(tmp,1,n,i,1);
}pre[a[i]]=i;
}printf("Case #%d:",++Cas);
int ans=0;
while(m--){
read(x);read(y);
int xx=(x+ans)%n+1,yy=(y+ans)%n+1;
x=min(xx,yy);y=max(xx,yy);
int u=query(root[x],1,n,x,y);
u=(u+1)/2;
ans=getans(root[x],1,n,u);
printf(" %d",ans);
}puts("");
}return 0;
}
HDU 5919 Sequence II(可持久化线段树)的更多相关文章
- HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)
HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...
- HDU 5919 Sequence II(主席树+逆序思想)
Sequence II Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5919 题意:给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组 ...
- HDU 5919 Sequence II 主席树
Sequence II Problem Description Mr. Frog has an integer sequence of length n, which can be denoted ...
- HDU 5919 Sequence II(主席树)题解
题意:有A1 ~ An组成的数组,给你l r,L = min((l + ans[i - 1]) % n + 1, (r + ans[i - 1]) % n + 1),R = max((l + ans[ ...
- hdu 5919 Sequence II (可持久化线段树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919 大致题意: 给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算 ...
- HDU 5919 -- Sequence II (主席树)
题意: 给一串数字,每个数字的位置是这个数第一次出现的位置. 每个询问对于序列的一个子区间,设一共有k个不同的数,求第ceil(k/2)个数的位置. 因为强制在线,所以离线乱搞pass掉. 主席树可解 ...
- HDU - 5919 Sequence II
题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...
- HDU 3397 Sequence operation 多标记线段树
/* 一开始维护了两个标记 开了两个数组 想的是 可能当前两种操作都要做 但是太复杂了 不好处理 其实 当前要做的标记可以只有一个 我们在Insert的时候 要打的标记是2即翻转区间: 1.如果原来是 ...
随机推荐
- http request parameter
http request parameter add htmlspecialchars host?vendor_id=1000000&q=Some%20children%20wish%20to ...
- redmine和svn server的部署
作为一个程序猿,想要很好的管理自己项目和代码,我们需要一些工具做辅助. 项目管理工具redmine和代码版本管理工具 SVN(Subversion). 我们选择在虚拟机里面安装windows部署这两套 ...
- Python自动化环境搭建
安装配置 Eclipse + PyDev + Robotframework 集成开发环境 1.安装JDK安装目录下的jdk-7u17-windows-i586.exe文件(JAVA开发.运行环境)安装 ...
- SQL Server 查看对象的权限
例子 1. 查看登录名 loginA的权限: create login loginA with password = '123456'; go use studio; create user logi ...
- @RISK
Price: AUD $3,295.00 Price: AUD $2,495.00 适用于项目管理的 @RISK 免费试用版下载 » 立即购买 » 价格对比 » 许可选项 (英文) » 教学计 ...
- JAVA仿真之银行出纳员
学习例子是参照<thinking in java>中修改的,先贴上运行结果: 注意看红框之中的内容,这个仿真要达到这样一个目的: 1.客户队列(无优先级):每隔300MILLS生产一个客户 ...
- java把函数作为参数传递
public class Tool { public void a()// /方法a { System.out.print("tool.a()..."); } public voi ...
- chroot 的用途
http://www.ibm.com/developerworks/cn/linux/l-cn-chroot/ http://liyongxian.blog.51cto.com/432519/1126 ...
- oracle导入导出exp,imp
exp dadifilm/oracle@dg file=/tmp/dadi.dmp full=y imp u_data/321@dg1 file=/dadi_desc.dmp Import: Rel ...
- MSSQL数库备份与还原脚本(多个库时很方便)
每次通过 Management Studio 的界面操作备份或还原数据库,对于单个数据库还好,要是一次要做多个.那就还是用脚本快些,下面有两段脚本分享一下. ===================== ...