题意:

给一串数字,每个数字的位置是这个数第一次出现的位置。

每个询问对于序列的一个子区间,设一共有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 (主席树)的更多相关文章

  1. HDU 5919 Sequence II 主席树

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

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

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

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

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

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

  5. hdu 5919 Sequence II (可持久化线段树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919 大致题意: 给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算 ...

  6. HDU5919 Sequence II(主席树)

    Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,anThere are ...

  7. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  8. HDU - 5919 Sequence II

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

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

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

随机推荐

  1. Java发送Http请求

    package com.liuyu.test; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...

  2. PHP开发者常犯的10个MySQL错误

    原文出处: kaiyuanba   欢迎分享原创到伯乐头条 数据库是WEB大多数应用开发的基础.如果你是用PHP,那么大多数据库用的是MYSQL也是LAMP架构的重要部分. PHP看起来很简单,一个初 ...

  3. MySQL5.7表空间加密

    MySQL5.7开始支持表空间加密了,增强了MySQL的数据文件的安全性,这是一个很不错的一个功能,这个特性默认是没有启用的,要使用这个功能要安装插件keyring_file. 下面就来看看怎么安装, ...

  4. 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(老罗学习笔记2)

    在前一篇文章中,我们介绍了如何在Ubuntu上为Android系统编写Linux内核驱动程序.在这个名为hello的Linux内核驱动程序中,创建三个不同的文件节点来供用户空间访问,分别是传统的设备文 ...

  5. Android中LayoutParams

    LayoutParams are used by views to tell their parents how they want to be laid out. See ViewGroup Lay ...

  6. C# Index 定义索---引具体使用2

    窗体代码 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;usi ...

  7. 自己动手实现STL 02:构造析构的基本工具construct()和destroy()(stl_construct.h)

    一.前言 上一篇,我先完成了对内存配置器的实现.然而后面在内存上的算法还依赖于两个全局函数,construct()和destroy(),前者负责在指定的内存上调用对象的构造函数,在内存上构造出对象.后 ...

  8. poj 2828 Buy Tickets (线段树)

    题目:http://poj.org/problem?id=2828 题意:有n个人插队,给定插队的先后顺序和插在哪个位置还有每个人的val,求插队结束后队伍各位置的val. 线段树里比较简单的题目了, ...

  9. MVVM设计模式《网摘》

    MVVM模式能够帮你把你程序的业务与展现逻辑从用户界面干净地分离开.保持程序逻辑与界面分离能够帮助解决很多开发以及设计问题,能够使你的程序能更容易的测试,维护与升级.它也能很大程度的增加代码重用性,并 ...

  10. 各浏览器各版本User-agent汇总 欢迎补充

    Internet Explorer Internet Explorer 5 Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; WOW64; Trident/ ...