E-Find the median_2019牛客暑期多校训练营(第七场)
题意
N次操作,每次塞入区间\([L,R]\)的每个数,并输出此时的中位数。
题解
如果题目不是每次塞入一整个区间,而是只塞入一个数,可以简单的建权值线段树查询区间第K大,由于每次都是查询整个区间就不用主席树了。
现在题目是塞一个区间,那么就要想办法把原来的权值线段树的单点更新变为区间更新,如果L,R的范围较小,可以很容易的把单点修改换成区间修改,题目范围是1e9不可能对整个1e9的区间建树,我们就需要对区间端点进行离散化,原来权值线段树的每一个点的含义由点变成了区间,例如1-5,6-10,离散化为为1-2,3-4,点1就表示1-5这个区间,点3表示6-10这个区间,
但是这样定义点的含义会有一点问题,比如1-5,5-10,离散化为1-2,2-3,此时点1表示1-5,点2表示5-10,点1和点2表示的区间重叠了,那如果我把点含义定义成左闭右开呢?点1表示1-4,点2表示5-9,点10表示10-10,此时如果我想更新1-5这个区间,会发现没法更新,这样定义也不行。
一种做法是把输入的区间右端点+1,比如上面的例子1-5,5-10,变成1-6,5-11,离散化后变成1-3,2-4,点1表示1-4,点2表示5-5,点3表示6-9,点4表示10-10,我要更新1-5只要更新点1和2就行了,问题得到解决。
代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int mx = 8e5+5;
int x[mx], y[mx];
vector <int> vv;
int getid(int x) {
return lower_bound(vv.begin(), vv.end(), x) - vv.begin() + 1;
}
struct Tree {
int lazy, len;
ll sum;
}tree[mx<<2];
void pushUp(int rt) {
tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
}
void pushDown(int rt) {
tree[rt<<1].lazy += tree[rt].lazy;
tree[rt<<1|1].lazy += tree[rt].lazy;
tree[rt<<1].sum += 1LL * tree[rt<<1].len * tree[rt].lazy;
tree[rt<<1|1].sum += 1LL * tree[rt<<1|1].len * tree[rt].lazy;
tree[rt].lazy = 0;
}
void build(int l, int r, int rt) {
if (l == r) {
tree[rt].len = vv[r+1-1] - vv[l-1];
tree[rt].sum = tree[rt].lazy = 0;
return;
}
int mid = (l + r) / 2;
build(l, mid, rt<<1);
build(mid+1, r, rt<<1|1);
tree[rt].len = tree[rt<<1].len + tree[rt<<1|1].len;
}
void update(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
tree[rt].sum += tree[rt].len;
tree[rt].lazy += 1;
return;
}
int mid = (l + r) / 2;
pushDown(rt);
if (L <= mid) update(L, R, l, mid, rt<<1);
if (mid < R) update(L, R, mid+1, r, rt<<1|1);
pushUp(rt);
}
int query(int l, int r, ll k, int rt) {
if (l == r) {
ll t = tree[rt].sum / tree[rt].len;
return vv[l-1] + (k-1) / t;
}
pushDown(rt);
int mid = (l + r) / 2;
if (tree[rt<<1].sum >= k) return query(l, mid, k, rt<<1);
else return query(mid+1, r, k-tree[rt<<1].sum, rt<<1|1);
}
int main() {
ll n, A1, B1, C1, M1, A2, B2, C2, M2;
scanf("%lld", &n);
scanf("%d%d%lld%lld%lld%lld", &x[1], &x[2], &A1, &B1, &C1, &M1);
scanf("%d%d%lld%lld%lld%lld", &y[1], &y[2], &A2, &B2, &C2, &M2);
for (int i = 3; i <= n; i++) {
x[i] = (A1*x[i-1] + B1*x[i-2] + C1) % M1;
y[i] = (A2*y[i-1] + B2*y[i-2] + C2) % M2;
}
for (int i = 1; i <= n; i++) {
if (x[i] > y[i]) swap(x[i], y[i]);
x[i]++; y[i]+=2;
vv.push_back(x[i]);
vv.push_back(y[i]);
}
sort(vv.begin(), vv.end());
vv.erase(unique(vv.begin(), vv.end()), vv.end());
vv.push_back(vv[vv.size()-1]+1);
build(1, vv.size()-1, 1);
ll sum = 0;
for (int i = 1; i <= n; i++) {
update(getid(x[i]), getid(y[i])-1, 1, vv.size()-1, 1);
sum += y[i]-x[i];
printf("%d\n", query(1, vv.size()-1, (sum-1)/2+1, 1));
}
return 0;
}
E-Find the median_2019牛客暑期多校训练营(第七场)的更多相关文章
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
- 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...
- [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem
链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 2019牛客暑期多校训练营(第二场)J-Subarray(思维)
>传送门< 前言 这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维 ...
- J-Subarray_2019牛客暑期多校训练营(第二场)
题意 有一个只由1,-1组成的数组,给出所有连续的1所在位置,求满足1的个数大于-1的个数的子区间的数量 题解 参考博客:https://www.cnblogs.com/Yinku/p/1122149 ...
随机推荐
- 1.Java概述、安装及环境搭建
1. 前言 1.1 学习方法 1. 学会学习的方法 2. 学会独立解决问题 3. 主动的学习而不是被动的接受 4. 知识的大家的,能力才是自己的 1.2 推荐博客 当代程序员都应该养成写博客.看博客的 ...
- 史上最全存储引擎、索引使用及SQL优化的实践
史上最全存储引擎.索引使用及SQL优化的实践 1 MySQL的体系结构概述 2. 存储引擎 2.1 存储引擎概述 2.2 各种存储引擎特性 2.2.1 InnoDB 2.2.2 MyISAM 3. 优 ...
- .net持续集成测试篇之Nunit常见断言
系列目录 Nunit测试基础之简单断言 在开始本篇之前需要补充一些内容,通过前面搭建Nunit测试环境我们知道要使一个方法成为单元测试方法首先要在此方法所在类加上TestFixture注解,并且在该方 ...
- 详细分享TortoiseGit配置密钥的方法
详细分享TortoiseGit配置密钥的方法 TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥.使用命令ssh-keygen -C "邮箱地址&q ...
- 01-Spring Security框架学习--入门(二)
一.入门案例 Spring Security 自定义登录界面 通过之前的一节 01-Spring Security框架学习--入门(一)的简单演示,Spring security 使用框架自带的登录界 ...
- Robotframework获取移动端toast问题
背景: 在做移动端自动化测试的时候,经常会遇到一个问题就是获取toast提示问题,如果需要解决这个问题需要重新处理,不能按照正常的逻辑,使用robotframework自带的关键字进行获取,需要重新考 ...
- RocketMQ中Broker的HA策略源码分析
Broker的HA策略分为两部分①同步元数据②同步消息数据 同步元数据 在Slave启动时,会启动一个定时任务用来从master同步元数据 if (role == BrokerRole.SLAVE) ...
- FTP工具-FileZilla安装使用教程
1.首先,百度搜索“FileZilla”,进入官网,下载地址:https://www.filezilla.cn/download/client ,根据自己电脑配置去下载 2.下载本地,双击运行安装程 ...
- 分享我的GD32F450的IAP过程
最近一个项目使用GD32F450VI+ESP8266需要做远程升级,基本参考正点原子IAP的那一章节,但是在GD32F450上却遇到了问题,无法跳转,然后使用正点原子的开发板stm32f429,以及s ...
- HelloDjango 第 09 篇:让博客支持 Markdown 语法和代码高亮
作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 为了让博客文章具有良好的排版,显示更加丰富的格式,我们使用 Markdown 语法来书 ...