【树状数组】【P4113】[HEOI2012]采花
Description
给定一个长度为 \(n\) 的序列,有 \(m\) 次询问,每次询问一段区间,求区间中有多少个数出现次数超过 \(1\) 次
Limitation
\(n,~m~\leq~2~\times~10^6\)
Solution
好像和大众做法不大一样?
考虑对于每个位置,我们记一个 pre
和一个 post
,代表他前面最后一个出现这个数的位置和他后面第一个出现这个数的位置。
考虑一个位置 \(x\) 对一个 \([l,~r]\) 的查询产生贡献当且仅当 \(pre_x~\geq~l\) 并且 \(post_x~>~r\)。
我们发现这个东西是可以树状数组维护的。
考虑统计一段区间内 pre
大于等于某个数的个数显然可以对 pre
开权值树状数组,然后按照左端点不升序排序,左端点左移的时候将对应位置的 pre
加入树状数组,一次查询的答案即为 \(BIT_{r}~-~BIT_{l - 1}\)。
现在考虑加入 \(post_x ~>~r\) 的限制。
我们发现当且仅当满足该条件的位置才对答案有贡献,于是我们只需要保证树状数组里只存有满足该条件的位置的 pre
,就可以统计答案了。考虑按照右端点不升序排序,一开始先将最后一次出现的数字的 pre
加入到树状数组中,每次移动右端点的时候,将 post
为右端点所在位置的位置的 pre
加入树状数组即可(即将 \(post_x~=~R\) 的 \(x\) 的对应 \(per_x\) 加入树状数组)。由于大于右端点的部分的 pre
对答案同样没有贡献了,所以移动右端点的时候别忘了把右端点对应的 pre
在树状数组上删除。
Code
#include <cstdio>
#include <vector>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
int top=0;
do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 2000010;
int n, c, m, dn;
int MU[maxn], oc[maxn], pos[maxn], pre[maxn], tree[maxn];
std::vector<int> vc[maxn];
struct Ask {
int l, r, id, ans;
inline bool operator<(const Ask &_others) const {
return this->r > _others.r;
}
};
Ask ask[maxn];
bool cmp(const Ask&, const Ask&);
int lowbit(int);
void update(int, int);
int query(int);
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(c); qr(m); dn = n + 1;
for (int i = 1; i <= n; ++i) {
qr(MU[i]); pre[i] = oc[MU[i]]; oc[MU[i]] = i;
}
for (int i = 1; i <= c; ++i) oc[i] = dn;
for (int i = n; i; --i) {
vc[pos[i] = oc[MU[i]]].push_back(i);
oc[MU[i]] = i;
}
for (int i = 1; i <= m; ++i) {
qr(ask[i].l); qr(ask[i].r); ask[i].id = i;
}
std::sort(ask + 1, ask + 1 + m);
for (auto i : vc[dn]) update(pre[i], 1);
for (int i = 1, R = n; i <= m; ++i) {
int l = ask[i].l, r = ask[i].r;
while (R > r) {
update(pre[R], -1);
for (auto j : vc[R]) update(pre[j], 1);
--R;
}
ask[i].ans = query(r) - query(l - 1);
}
std::sort(ask + 1, ask + 1 + m, cmp);
for (int i = 1; i <= m; ++i) {
qw(ask[i].ans, '\n', true);
}
return 0;
}
inline bool cmp(const Ask &_a, const Ask &_b) {
return _a.id < _b.id;
}
inline int lowbit(int x) {return x & -x;}
void update(int x, int v) {
if (x == 0) return;
while (x <= dn) {
tree[x] += v;
x += lowbit(x);
}
}
int query(int x) {
int _ret = 0;
while (x) {
_ret += tree[x];
x -= lowbit(x);
}
return _ret;
}
【树状数组】【P4113】[HEOI2012]采花的更多相关文章
- 洛谷P4113 [HEOI2012]采花
题目描述 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花. 花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于 ...
- P4113 [HEOI2012]采花 (莫队TLE)
思路 update 11.2 树状数组AC 本题莫队过不去,会TLE ----------------------- 但也是个不错的莫队练手题 ------------------------ 毕竟C ...
- P4113 [HEOI2012]采花
题目描述 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花. 花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于 ...
- 【luogu P4113 [HEOI2012]采花】 假题解
题目链接:https://www.luogu.org/problemnew/show/P4113 为什么要卡莫队!为什么加强的这么毒瘤! 莫队可以拿100分剩下三个点没治了 // luogu-judg ...
- LUOGU P4113 [HEOI2012]采花
传送门 解题思路 莫队题卡莫队...莫队只能拿到100分,满分200.正解主席树??发个莫队100分代码. 代码 #include<iostream> #include<cstdio ...
- BZOJ_2743_[HEOI2012]采花_离线+树状数组
BZOJ_2743_[HEOI2012]采花_离线+树状数组 Description 萧芸斓是Z国的公主,平时的一大爱好是采花.今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花 .花园足够大 ...
- BZOJ 2743: [HEOI2012]采花 离线树状数组
2743: [HEOI2012]采花 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2743 Description 萧芸斓是Z国的公主, ...
- 【BZOJ2743】[HEOI2012]采花 离线+树状数组
[BZOJ2743][HEOI2012]采花 Description 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花, ...
- 【bzoj2743】[HEOI2012]采花 树状数组
题目描述 萧芸斓是Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于公 ...
随机推荐
- c++ 整数和字符串的转化
一.string转int的方式 采用最原始的string, 然后按照十进制的特点进行算术运算得到int,但是这种方式太麻烦,这里不介绍了. 采用标准库中atoi函数. "; int a = ...
- sqlmap 进阶 (一)
0x1 命令 以此类推,可以具体自己研究有哪些参数,放在哪,有什么用,怎么用 参考:https://blog.csdn.net/bo_mask/article/details/76130848 0x2 ...
- linux 常用命令-文件、文件夹管理
1. 创建文件夹: mkdir dirName 删除文件夹: rm -rf * 删除当前目录下的所有文件以及文件夹(非交互式) rm -r --recursive 递归式删除所删除目录以及子目录(有 ...
- Oracle安装后出现的问题
安装oracle没有勾选"安装模板数据库",可以通过执行以下命令进行修改: cd $ORACLE_HOME/rdbms/admin 到这个目录下sqlplus /as sysdba ...
- Android笔记-3-EditText的属性介绍
[Android 基础]EditText的属性介绍 EditText继承TextView,所以EditText具有TextView的属性特点,下面主要介绍一些EditText的特有的输入法的属性特点 ...
- Good Time 冲刺 五
一.今日完成任务情况及遇到的问题 第五天 日期:2018.6.18 王怡镔:今天继续在学习中完善编写页面,对之前的页面进行部分改进. 于鑫宇:修改完善布局,复习. 胡雅馨:今天继续改进页面,努力解决时 ...
- Alpha阶段事后诸葛分析
一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件主要是解决在宿舍中购买商品的软件,不同于淘宝等软件,本软件主要是用于学生开设的店铺及宿 ...
- d指针在Qt上的应用及实现(有图,很清楚)
Qt为了使其动态库最大程度上实现二进制兼容,引入了d指针的概念.那么为什么d指针能实现二进制兼容呢?为了回答这个问题,首先弄清楚什么是二进制兼容?所谓二进制兼容动态库,指的是一个在老版本库下运行的程序 ...
- vue 笔记1
created 钩子可以用来在一个实例被创建之后执行代码: new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 实例 co ...
- Flyway学习笔记
Flyway做为database migration开源工具,功能上像是git.svn这种代码版本控制.google搜索database migration,或者针对性更强些搜索database mi ...