题意

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. TCP三次握手和断开四次挥手

    TCP三次握手 1主机A发送消息请求与主机B连接 2主机B回复消息同意与主机A连接 3主机A确认主机B的同意连接,并建立连接 TCP的四次挥手 1客户端发送FIN到服务器,请求关闭与服务器的连接(意思 ...

  2. T-SQL 日期

    --日期查询格式 ) --R:06/17/2011 ) --R:2011.06.17 ) --R:17/06/2011 ) --R:17.06.2011 ) --R:17-06-2011 ) --R: ...

  3. Selenium+java - 下拉框处理

    常见下拉框也分两种:一种是标准控件和非标准控件(一般为前端开发人员自己封装的下拉框),本篇文章中将重点讲解标准下拉框操作. 1.Select提供了三种选择某一项的方法 select.selectByI ...

  4. codeforces 322 B Ciel and Flowers

    题目链接 有红绿蓝三种颜色的画,每种拿三朵可以组成一束花,或者各拿一朵组成花束,告诉你每种花的数目,求出可能组成最多的花束. 如果你的代码过不了,考虑一下 8 8 9这种组合.  因为数据量很大,我的 ...

  5. Java虚拟机学习笔记(一)之初识

    一:特定 跨平台性.安全性.可移植性. 二:体系机构 Java 体系结构包括四个独立但相关的技术: Java程序设计语言 Java Class文件格式 Java 应用编程接口(API) Java 虚拟 ...

  6. Android--SharedPreferences数据存储方案

            SharedPreferences是使用键值对的形式存储的,并且支持多种不同的数据类型,存的是String,取得值也是String.         使用SharedPreferenc ...

  7. php sql 类似 mybatis 传参

    PHP sql 处理上,没有类似于 java mybatis 的工具,导致进行一些sql 处理时,会有诸多不便, 楼主抽时间写了一个 php 类似 mybatis 的sql 工具,省去了拼装sql 的 ...

  8. Redis批量删除key的小技巧,你知道吗?

    在使用redis的过程中,经常会遇到要批量删除某种规则的key,但是redis提供了批量查询一类key的命令keys或scan,没有提供批量删除某种规则key的命令,怎么办?看完本文即可,哈哈. 本文 ...

  9. 0x15 字符串

    KMP算法 next数组的求法 void calc_next() { next[]=; , j=; i<=n; ++i) { &&a[i]!=a[j+]) j=next[j]; ...

  10. java并发编程(二)----创建并运行java线程

    实现线程的两种方式 上一节我们了解了关于线程的一些基本知识,下面我们正式进入多线程的实现环节.实现线程常用的有两种方式,一种是继承Thread类,一种是实现Runnable接口.当然还有第三种方式,那 ...