HDU5919 Sequence2
这道题是主席树好题啊……
####### 题目大意:给定一个序列,每次给定一段区间,区间内所有不同的数第一次出现的位置排成一个序列,求这个序列的中位数。
其实求中位数并不是很难,只要我们能把这个序列中不同的数出现的位置都求出,就能很直接的转化为用主席树求静态第k小的问题。首先我们考虑一下如何计算区间内有多少个不同的数,如果离线的话这个问题可以用莫队或者树状数组处理,但是本题因为强制在线,所以需要用主席树处理。具体的方法很巧妙,因为我们要维护的是最左边的第一次出现的值,所以我们倒着插入。因为维护的是位置,所以我们用第\(i\)棵主席树维护区间\(i~r\)内所有不同的数出现的次数(也就是主席树以位置为值域),以每个数的位置为权值在树上进行二分。当一个数在一起出现过一次的时候,我们就先找到它原来所在的位置,把它从树上删除,之后再在它的新位置加入这个数,更改这个数原来的位置即可。
至于查询的时候,我们就可以只查询第l棵主席树上的情况了,我们像线段树一样\(query\)一下这个树上有多少不同的数,之后仿照模板 ,在树上二分求静态第k小即可。
然后还有一道题是它的弱化版here 此题不强制在线不用求第k大,不过数的范围大了一点,所以需要把记录位置的数组稍微开大一点才行。
本题千万要注意一下输出格式!修改的时候一定要按代码中顺序修改,如果倒过来的话,一旦这个数是第一次出现就会出错(没继承上一个根的信息)。
看一下代码。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define fr friend inline
#define y1 poj
#define mp make_pair
#define pr pair<int,int>
#define fi first
#define sc second
#define pb push_back
using namespace std;
typedef long long ll;
const int M = 200005;
const int N = 2000005;
const int INF = 1000000009;
const double eps = 1e-7;
int read()
{
int ans = 0,op = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-') op = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
ans *= 10;
ans += ch - '0';
ch = getchar();
}
return ans * op;
}
struct node
{
int lson,rson,v;
}t[N<<2];
int T,n,m,l,r,a[M],pos[M],idx,root[M],la;
void modify(int old,int &p,int l,int r,int pos,int val)
{
p = ++idx;
t[p].lson = t[old].lson,t[p].rson = t[old].rson,t[p].v = t[old].v + val;
if(l == r) return;
int mid = (l+r) >> 1;
if(pos <= mid) modify(t[old].lson,t[p].lson,l,mid,pos,val);
else modify(t[old].rson,t[p].rson,mid+1,r,pos,val);
}
int query(int p,int l,int r,int kl,int kr)
{
if(l == kl && r == kr) return t[p].v;
int mid = (l+r) >> 1;
if(kr <= mid) return query(t[p].lson,l,mid,kl,kr);
else if(kl > mid) return query(t[p].rson,mid+1,r,kl,kr);
else return query(t[p].lson,l,mid,kl,mid) + query(t[p].rson,mid+1,r,mid+1,kr);
}
int ask(int p,int l,int r,int k)
{
if(l == r) return l;
int mid = (l+r) >> 1;
if(t[t[p].lson].v >= k) return ask(t[p].lson,l,mid,k);
else return ask(t[p].rson,mid+1,r,k - t[t[p].lson].v);
}
void clear()
{
memset(root,0,sizeof(root));
memset(pos,0,sizeof(pos));
idx = la = 0;
}
int main()
{
//freopen("1.out","w",stdout);
T = read();
rep(i,1,T)
{
printf("Case #%d:",i);
n = read(),m = read();
rep(j,1,n) a[j] = read();
per(j,n,1)
{
modify(root[j+1],root[j],1,n,j,1);
if(pos[a[j]]) modify(root[j],root[j],1,n,pos[a[j]],-1); //Accepted
pos[a[j]] = j;
}
rep(j,1,m)
{
l = read(),r = read();
l = (l + la) % n + 1,r = (r + la) % n + 1;
if(l > r) swap(l,r);
//printf("#%d %d\n",l,r);
int cur = query(root[l],1,n,l,r);
la = ask(root[l],1,n,(cur+1)>>1);
printf(" %d",la);
}
enter;
clear();
}
return 0;
}
HDU5919 Sequence2的更多相关文章
- HDU5568/BestCoder Round #63 (div.2) B.sequence2 dp+高精度
sequence2 Problem Description Given an integer array bi with a length of n, please tell me how many ...
- Hdu 5568 sequence2 高精度 dp
sequence2 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=556 ...
- sequence2(高精度dp)
sequence2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- 【HDU5919】SequenceII(主席树)
[HDU5919]SequenceII(主席树) 题面 Vjudge 翻译(by ppl) 给一个长度为N的数列A,有m个询问,每次问 数列[l,r]区间中所有数的第一次出现的位置的中位 数是多少 题 ...
- [HDU5919]Sequence II
[HDU5919]Sequence II 试题描述 Mr. Frog has an integer sequence of length n, which can be denoted as a1,a ...
- HDU 5568:sequence2 大数+DP
sequence2 Accepts: 93 Submissions: 358 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 6553 ...
- HDU 5568 sequence2 区间dp+大数
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意: 求所有长度为k的严格升序子序列的个数. 题解: 令dp[i][k]表示以i结尾的长度为 ...
- HDU 5568 - BestCoder Round #63 - sequence2
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5568 题意 : 给一个长度已知的序列, 给一个值k, 问该序列中有多少种长度为k的上升子序列 思路 ...
- HDU5919:Sequence II
题面 Vjudge Sol 给一个数列,有m个询问,每次问数列[l,r]区间中所有数的第一次出现的位置的中位数是多少,强制在线 主席树 询问区间内不同的数的个数 树上二分找到那个中位数 # inclu ...
随机推荐
- Git以及github的使用方法(二)创建仓库,git add添加到“暂储区”,git commit添加到“本地仓库”
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或 ...
- 百科知识 DCR文件如何打开
使用IE可以打开,但是需要先安装Adobe Shockwave Player 天空软件下载地址:http://fpdownload.macromedia.com/get/shockwave/defau ...
- PS 基础知识 如何绘制几何图形
注意:规则的几何图形必须用路径工具,如果使用简单的椭圆工具再描边,则效果是像素堆砌起来的.图像一旦放大就是出现明显的失真. 使用钢笔工具,然后选择路径工具,然后选择需要绘制的图形. 如果需要找 ...
- UVA - 11354Bond最小生成树,LCA寻找近期公共祖先
看懂题目意思.他的意思是求将全部的城市走一遍,危急度最小.而且给 你两个s,t后让你求在走的时候,从s到t过程中危急度最大的值,并输出它, 然后就是怎样攻克了,这个题目能够说简单,也能够说难 通过思考 ...
- USB通讯协议
首先要了解USB枚举过程(自己百度) https://blog.csdn.net/MyArrow/article/details/8270029 USB通讯协议 0. 基本概念 一个[传输](控制.批 ...
- 英特尔和Red Hat合作实现Gnome桌面的Wayland支持
在发布支持XMir的Linux图形驱动程序xf86-video-intel 2.99.901后数天,英特尔宣布撤回对XMir的支持,XMir补丁不会合并到上游项目.XMir是Mir显示服务器的X11兼 ...
- 在eclipse中查找指定文件 [多种方法]
在eclipse中查找指定文件 1.ctrl+h打开搜索界面 File Search: containing text填*,File name patterns填写hello.*,可以找到hell ...
- Spring Cloud(十一):Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式
上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制,但其实Zuul还有更多的应用场景,比如:鉴权.流量转发.请求统计等等,这些功能都可以使用Zuul来实现. Zuul的核心 Filter是Zuu ...
- hessian实战1
服务端: 1.新建MAVEN HessianServer 项目 2.新建接口 Basic public interface Basic { String hello(String name); Str ...
- JavaScript读书笔记(2)--数据类型
1. 严格模式:在javascript中定义了一种不同的解析与执行模型.在严格模式下,一些不确定的行为将得到处理,对某些不安全的操作也会抛出错误. 用法是在脚本中添加:”use strict”; 这 ...