题意

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牛客暑期多校训练营(第七场)的更多相关文章

  1. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  2. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  3. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  4. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  5. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  6. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  7. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  8. 2019牛客暑期多校训练营(第二场)J-Subarray(思维)

    >传送门< 前言 这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维 ...

  9. J-Subarray_2019牛客暑期多校训练营(第二场)

    题意 有一个只由1,-1组成的数组,给出所有连续的1所在位置,求满足1的个数大于-1的个数的子区间的数量 题解 参考博客:https://www.cnblogs.com/Yinku/p/1122149 ...

随机推荐

  1. Calico 网络通信原理揭秘

    Calico 是一个纯三层的数据中心网络方案,而且无缝集成像 OpenStack 这种 Iaas 云架构,能够提供可控的 VM.容器.裸机之间的 IP 通信.为什么说它是纯三层呢?因为所有的数据包都是 ...

  2. Reactv16.8.6生命周期函数

    组件生命周期函数 React 主动调用的方法,也可重写这些方法 生命周期图谱 当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下: constructor(props) 如果不需要初始化 s ...

  3. CoreCLR Host源码分析(C++)

    废话不多说,直接上源码: 1.在托管程序集里面执行方法 HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,//通过CreateAppDomai ...

  4. Ping、Traceroute工作原理

    在工作开发过程中,我们经常会使用到ping和traceroute.在这里,我们将细述其工作原理,让你在会用的基础之上理解其内部工作过程. ICMP应用实例--Ping Ping 是 ICMP 的一个重 ...

  5. NLP(十三)中文分词工具的使用尝试

      本文将对三种中文分词工具进行使用尝试,这三种工具分别为哈工大的LTP,结巴分词以及北大的pkuseg.   首先我们先准备好环境,即需要安装三个模块:pyltp, jieba, pkuseg以及L ...

  6. redis过期策略与内存淘汰机制分析

    过期策略: 我们在set key时,可以给一个expire time,就是过期时间 这段过期时间以后,redis对key删除使用:定期删除+惰性删除 定期删除指redis默认在100ms内随机抽取一些 ...

  7. .net持续集成测试篇之Nunit文件断言、字符串断言及集合断言

    使用前面讲过的方法基本上能够完成工作中的大部分任务了,然而有些功能实现起来还是比较麻烦的,比如说字符串相等性比较不区分大小写,字符串是否匹配某一正则规则,集合中的每一个(某一个)元素是否符合特定规则等 ...

  8. (13)ASP.NET Core 中的选项模式(Options)

    1.前言 选项(Options)模式是对配置(Configuration)的功能的延伸.在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类.绑定至对 ...

  9. 数据结构之二叉树的构建C++版

    二叉树的构建要注意与链式表的区别,二叉树这里的构建十分低级,每个树只是构建了一个单一的二叉树节点,总体来看是有下向上构建的.用户需要手动去构建自己需要的树,而不是直接去插入数据就到二叉树中了,因为不是 ...

  10. JS中map()与forEach()的区别和用法

    相同点: 1.都是循环遍历数组中的每一项 2.每次执行匿名函数都支持三个参数,参数分别为item(当前每一项),index(索引值),arr(原数组) 3.匿名函数中的this都是指向window 4 ...