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 ...
随机推荐
- JUint4的下载、配置及对一个算法编写单元测试用例(测试多组数据每组多个参数)
一.JUnit4 jar包下载 链接:https://pan.baidu.com/s/1AdeVGGikcY5dfL151ZnWHA 提取码:h1am 下载完成后,解压一下即可. 二.导入JUnit4 ...
- 遇见Python集合类型
Python目前有两种内置集合类型,set和frozenset. Ⅰ.两者区别 set是可变的,没有哈希值,其内容可以使用add()和remove()这样的方法来改变,所以不能被用作字典的键或其他集合 ...
- Spring Boot中自定义注解+AOP实现主备库切换
摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...
- docker挂载volume的用户权限问题,理解docker容器的uid
docker挂载volume的用户权限问题,理解docker容器的uid 在刚开始使用docker volume挂载数据卷的时候,经常出现没有权限的问题. 这里通过遇到的问题来理解docker容器用户 ...
- 非web下的PowerMockito单元测试
一.介绍 PowerMockito 可以用来 Mock 掉 final 方法(变量).静态方法(变量).私有方法(变量).想要使用 PowerMockito Mock掉这些内容,需要在编写的测试类上使 ...
- sharding demo 读写分离 U (分库分表 & 不分库只分表)
application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...
- STL set 详细用法
一个集合(set)是一个容器,它其中所包含的元素的值是唯一的. 用到的库 #include <set> 定义 最简单: set<int> a; set和其他的stl一样,都支持 ...
- Why do I write a blog
I believe the most beautiful and elegant answer to this question is from Churchill. "On a peace ...
- Spring Cloud与Dubbo的完美融合之手「Spring Cloud Alibaba」
很早以前,在刚开始搞Spring Cloud基础教程的时候,写过这样一篇文章:<微服务架构的基础框架选择:Spring Cloud还是Dubbo?>,可能不少读者也都看过.之后也就一直有关 ...
- 性能测试学习第四天-----loadrunner:jdbc批量制造测试数据 & controller应用
Javavuser协议 1.过程概述:在eclipse中用java编写sql执行脚本,复制到lr中,调整后通过参数化迭代批量制造测试数据: 2.步骤: 1).在eclipse中新建java proje ...