链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919

大致题意:

给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算会得到一个区间[x,y],假设这个区间内有k个数,对k个数第一次出现的位置进行排序取第(k+1)/2个数。

思路:

看题意可知要求的是区间不同数的个数和区间第k小,强制在线,

之前正好写过求区间不同数的个数的三种解法:离线树状数组,主席树,莫队,因为这道题是强制在线,莫队和离线树状数组都不能用,这里就直接用主席树了。

题目要求各个数第一次出现的位置,那么我们只要从后向前插入,重复出现的取消之前的标记,这样维护的标记就都是当前坐标i到n区间内第一次出现的,用主席树维护下就好了。

用主席树求出区间不同数的个数num后, 直接再求区间第(num+1)/2小就好了

注意数组要开大点。。之前数组开小了 超时了

实现代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5 + ;
#define mid int m = (l + r) >> 1
int ls[M*],rs[M*],sum[M*],root[M],a[M],vis[M],idx,ans[M],n; void init()
{
idx = ;root[n+] = ; ans[] = ;
memset(ls,,sizeof(ls));
memset(vis,,sizeof(vis));
memset(rs,,sizeof(rs));
memset(sum,,sizeof(sum));
} void update(int old,int &k,int l,int r,int p,int c){
k = ++idx;
ls[k] = ls[old]; rs[k] = rs[old];
sum[k] = sum[old] + c;
if(l == r) return ;
mid;
if(p <= m) update(ls[old],ls[k],l,m,p,c);
else update(rs[old],rs[k],m+,r,p,c);
} int query(int x,int L,int R,int l,int r){ //求区间不同数的个数
if(L <= l&&R >= r) return sum[x];
mid,ret = ;
if(L <= m) ret += query(ls[x],L,R,l,m);
if(R > m) ret += query(rs[x],L,R,m+,r);
return ret;
} int query1(int x,int l,int r,int k){ //求区间第k小
if(l == r) return l;
mid,ret = sum[ls[x]];
if(ret >= k) return query1(ls[x],l,m,k);
else return query1(rs[x],m+,r,k - ret);
} int main()
{
int t,cas = ,q,x,y;
scanf("%d",&t);
while(t--){
init();
scanf("%d%d",&n,&q);
for(int i = ;i <= n;i ++) scanf("%d",&a[i]);
for(int i = n;i >= ;i --){
int tmp = ;
if(vis[a[i]] == ) update(root[i+],root[i],,n,i,); //添加新标记
else{
update(root[i+],tmp,,n,vis[a[i]],-); //把之前的标记清掉
update(tmp,root[i],,n,i,); //添加新标记
}
vis[a[i]] = i;
}
for(int i = ;i <= q;i ++){
scanf("%d%d",&x,&y);
x = ((x + ans[i-])%n) + ;
y = ((y + ans[i-])%n) + ;
if(x > y) swap(x,y); //倒着输入的,所以取较小的
int num = (query(root[x],x,y,,n) + ) >> ; //得到中位数是区间内第num/2小的数
ans[i] = query1(root[x],,n,num); //求区间内第(num+1)/2小的数
}
printf("Case #%d: ",cas++);
for(int i = ;i < q;i ++) printf("%d ",ans[i]);
printf("%d\n",ans[q]);
}
return ;
}

hdu 5919 Sequence II (可持久化线段树)的更多相关文章

  1. HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)

    HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...

  2. HDU 5919 Sequence II(可持久化线段树)

    [题目链接]http://acm.hdu.edu.cn/showproblem.php?pid=5919 [题目大意] 给出一个数列,每次查询数列中,区间非重元素的下标的中位数.查询操作强制在线. [ ...

  3. HDU 5919 Sequence II(主席树+逆序思想)

    Sequence II Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

  4. HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5919 题意:给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组 ...

  5. HDU 5919 Sequence II 主席树

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

  6. 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[ ...

  7. HDU 5919 -- Sequence II (主席树)

    题意: 给一串数字,每个数字的位置是这个数第一次出现的位置. 每个询问对于序列的一个子区间,设一共有k个不同的数,求第ceil(k/2)个数的位置. 因为强制在线,所以离线乱搞pass掉. 主席树可解 ...

  8. HDU - 5919 Sequence II

    题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...

  9. HDU 3397 Sequence operation 多标记线段树

    /* 一开始维护了两个标记 开了两个数组 想的是 可能当前两种操作都要做 但是太复杂了 不好处理 其实 当前要做的标记可以只有一个 我们在Insert的时候 要打的标记是2即翻转区间: 1.如果原来是 ...

随机推荐

  1. ARM的9种寻址方式

    立即寻址 操作数是立即数,以“#”为前缀,表示 16 进制数值时以“0x”表示. 例: MOV   R0,#0xFF00   ;0xFF00 ->  R0 SUBS   R0,R0,#1     ...

  2. eclipse的快捷键【转载】

    原文地址http://www.open-open.com/bbs/view/1320934157953/ Eclipse中10个最有用的快捷键组合  一个Eclipse骨灰级开发者总结了他认为最有用但 ...

  3. 最全的前端Git基础命令,看完保证你会!

    常见信息 master: 默认开发分支 origin:默认远程版本库 Head: 默认开发分支 Head^:Head 的父提交 创建新仓库 git init git init [project-nam ...

  4. asp.net core部署时自定义监听端口,提高部署的灵活性

    另一种方式 https://www.cnblogs.com/stulzq/p/9039836.html 代码截图: 贴一下代码,方便复制: //默认端口号5000 string port = &quo ...

  5. CSharp 案例:用 Dynamic 来解决 DataTable 数值累加问题

    需求说明 给定一个 DataTable,如果从中取出数值类型列的值并对其累加? 限制:不知该列是何种数值类型. 解决方案 1.将表转换为 IEnumerable<dynamic>,而后获取 ...

  6. 微信扫描 安卓和ios 不会

    wx.ready(function(){ $('#scan').click(function(){ wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1 ...

  7. HDU 3537 Daizhenyang's Coin

    链接 [http://acm.hdu.edu.cn/showproblem.php?pid=3537] 题意 题意:已知一排硬币中有n个硬币正面朝上,输入正面朝上的硬币的位置ai.两人轮流操作, 每次 ...

  8. Microsoft Visual Studio 2013安装及试用

    我是在网上下载的vs2013版的安装包,下载的是压缩文件,解压后是2.86GB.安装包下载完成后我们就可以进入安装了. 同时建议最好在互联网连接的情况下安装. 打开下载好的文件,我们要选择.exe可执 ...

  9. PairProject 电梯调度 【附加题】

    [附加题] 改进电梯调度的interface 设计, 让它更好地反映现实, 更能让学生练习算法, 更好地实现信息隐藏和信息共享. 目前的设计有什么缺点, 你会如何改进它? 1.之前判断电梯是否闲置的函 ...

  10. Linux内核总结博客 20135332武西垚

    http://www.cnblogs.com/wuxiyao/p/5220677.htmlhttp://www.cnblogs.com/wuxiyao/p/5247571.htmlhttp://www ...