HDU 5919 -- Sequence II (主席树)
题意:
给一串数字,每个数字的位置是这个数第一次出现的位置。
每个询问对于序列的一个子区间,设一共有k个不同的数,求第ceil(k/2)个数的位置。
因为强制在线,所以离线乱搞pass掉。
主席树可解。
考虑一个数列:
p 1 2 3 4 5 6 // 原序列标号
a : 1 2 1 2 3 4 // 原序列
p1 1 2 1 2 5 6 // 子序列开始下标为1
p2 2 3 1 5 6
p3 3 4 5 6
p4 4 5 6
p5 5 6
p6 6
有一个规律就是对于以L为开始的子序列来说,只要求出[L, N]的子区间,R是不影响P(L)数组的。
那么就想到将数组倒过来建主席树。
树里存的是什么呢????
存的是…【此处想了10分钟……】…区间内不同数的个数(只考虑第一次出现的)
那么在用一个数组记录每个数第一个出现的位置,每添加一个数,该位置+1,如果一个数之前出现过,那么就要更改之前第一次出现的位置-1。
不是很会主席树,之前就写过一道模板题= = 强行没看题解,一顿乱搞还是搞出来了,但是估计写的很麻烦

#include <bits/stdc++.h>
using namespace std; const int N = ; struct node {
int l, r, v;
} T[N*]; int a[N];
int pos[N];
int root[N], cnt;
int ans;
// y is x previous version
void update(int l, int r, int &x, int y, int p, int v) {
T[++cnt] = T[y], T[cnt].v += v; x = cnt;
if (l == r) return ;
int mid = (l+r) >> ;
if (mid >= p) update(l, mid, T[x].l, T[y].l, p, v);
else update(mid+, r, T[x].r, T[y].r, p, v);
} // p1 > p2
void update(int l, int r, int &x, int y, int p1, int v1, int p2, int v2) {
T[++cnt] = T[y]; x = cnt;
if (l == r) return ;
int mid = (l+r) >> ;
// three conditions
// p1 > mid >= p2, p1 > p2 > mid, mid >= p1 > p2
if (p1 > mid && p2 <= mid) {
update(mid+, r, T[x].r, T[y].r, p1, v1);
update(l, mid, T[x].l, T[y].l, p2, v2);
} else if (p2 > mid) {
update(mid+, r, T[x].r, T[y].r, p1, v1, p2, v2);
} else {
update(l, mid, T[x].l, T[y].l, p1, v1, p2, v2);
}
} void query(int l, int r, int x, int k) {
if (l == r) {
ans = l; return ;
}
int mid = (l+r) >> ;
if (T[T[x].r].v >= k) {
ans = mid+;
query(mid+, r, T[x].r, k);
} else {
query(l, mid, T[x].l, k-T[T[x].r].v);
}
} int query(int l, int r, int x, int L, int R) {
if (l >= L && r <= R) return T[x].v;
int mid = (l+r) >> ;
int ans = ;
if (mid >= L) ans += query(l, mid, T[x].l, L, R);
if (mid < R) ans += query(mid+, r, T[x].r, L, R);
return ans;
} int main()
{
//freopen("in.txt", "r", stdin);
int t, cas = ;
scanf("%d", &t); while (t--) {
printf("Case #%d:", ++cas);
ans = ;
int n, q, l_, r_, l, r, k;
scanf("%d%d", &n, &q);
memset(pos, , sizeof pos); cnt = ;
for (int i = ; i <= n; ++i) scanf("%d", &a[n-i+]);
for (int i = ; i <= n; ++i) {
if (pos[a[i]]) update(, n, root[i], root[i-], i, , pos[a[i]], -);
else update(, n, root[i], root[i-], i, );
pos[a[i]] = i;
}
while (q--) {
scanf("%d%d", &l_, &r_);
l_ = (l_ + ans) % n + ;
r_ = (r_ + ans) % n + ;
l = min(l_, r_);
r = max(l_, r_);
l = n-l+, r = n-r+; swap(l, r);
k = query(, n, root[r], l, r);
query(, n, root[r], ceil(k/2.0));
ans = n-ans+;
printf(" %d", ans);
}
printf("\n");
}
return ;
}
HDU 5919 -- Sequence II (主席树)的更多相关文章
- 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(主席树+逆序思想)
Sequence II Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)
HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...
- 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,经过与上一次的答案进行运算 ...
- HDU5919 Sequence II(主席树)
Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,anThere are ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- HDU - 5919 Sequence II
题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...
- HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5919 题意:给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组 ...
随机推荐
- 重写hashCode()的方法
重写hashCode()方法的基本规则: 1.在程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值 2.当两个对象通过equals()方法比较返回true时,这两个对象的has ...
- hadoop2 环境的搭建(手动HA)
1.手工切换ha的环境的搭建(比hadoop1多出来journalnode的配置) namenode:hadoop110和hadoop111 datanode:hadoop112.hadoop113. ...
- 【HDOJ】4080 Stammering Aliens
1. 题目描述给定一个长为$n \in [1, 4000]$的字符串,求其中长度最长的子串,并且该子串在原串中出现至少$m$次,并求最右起始位置. 2. 基本思路两种方法:二分+后缀数组,或者二分+哈 ...
- Hadoop集群(第7期)_Eclipse开发环境设置
1.Hadoop开发环境简介 1.1 Hadoop集群简介 Java版本:jdk-6u31-linux-i586.bin Linux系统:CentOS6.0 Hadoop版本:hadoop-1.0.0 ...
- 1450. Russian Pipelines(spfa)
1450 水题 最长路 #include <iostream> #include<cstdio> #include<cstring> #include<alg ...
- 关于fft的一点总结
好吧,其实我并没有深入运用fft,只会优化卷积 听说fft经常和生成函数结合在一起………………oi真是迅猛发展,我真是与时代脱节了…… 关于fft的学习推荐直接去看算法导论,写得非常清楚 主要弄懂n次 ...
- bzoj3926
题目的意思是叶子不超过20个……听说当初zjoi不少人被坑 分别对每个叶子以它为根dfs出20个dfs树,这样整个树的任何一个子串,都是某个dfs树上一个点到它的一个子孙的路径 每个dfs树,根到叶子 ...
- DbgPrint输出格式 Unicodestring
DbgPrint输出格式 Unicodestring 1) 直接打印字符串. DbgPrint("Hello World!"); 2) 空结尾的字符串,你可以用普通得C语法表示字 ...
- H264码流打包分析(精华)
H264码流打包分析 SODB 数据比特串-->最原始的编码数据 RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若 ...
- poj 1087 A Plug for UNIX
题目描述:现在由你负责布置Internet联合组织首席执行官就职新闻发布会的会议室.由于会议室修建时被设计成容纳全世界各地的新闻记者,因此会议室提供了多种电源插座用以满足(会议室修建时期)各国不同插头 ...