2019牛客多校第七场E Find the median 权值线段树+离散化
Find the median
题目链接:
https://ac.nowcoder.com/acm/contest/887/E
题目描述
Let median of some array be the number which would stand in the middle of this array if it was sorted beforehand. If the array has even length let median be smallest of of two middle elements. For example, median of the array \([10,3,2,3,2]\) is 3 (i.e. \([2,2,\underline{3},3,10]\)). Median of the array [1,5,8,1] is 1 (i.e. \([1,\underline{1},5,8]\)).
At first, you're given an empty sequence. There are N operations. The i-th operation contains two integers \(L_i\) and \(R_i\). This means that adding \(R_i-L_i+1\) integers \(L_i, L_i+1, ... , R_i\) into the sequence. After each operation, you need to find the median of the sequence.
输入描述:
The first line of the input contains an integer \(N\ (1 \leq N \leq 400000)\) as described above.
The next two lines each contains six integers in the following format, respectively:
- \(X_1\ X_2\ A_1\ B_1\ C_1\ M_1\)
- \(Y_1\ Y_2\ A_2\ B_2\ C_2\ M_2\)
These values are used to generate \(L_i, R_i\) as follows:
We define:
- \(X_i = (A_1 \times X_{i-1} + B_1 \times X_{i-2} + C_1)\ module\ M_1\), for \(i= 3\ to\ N\)
- \(Y_i = (A_2 \times Y_{i-1} + B_2 \times Y_{i-2} + C_2)\ module\ M_2\), for \(i = 3\ to\ N\)
We also define:
- \(L_i = min(X_i, Y_i) + 1\), for \(i = 1\ to\ N\).
- \(R_i = max(X_i, Y_i) + 1\), for \(i = 1\ to\ N\).
Limits:
\(1 \leq N \leq 400000\)
\(0 \leq A_1 < M_1\)
\(0 \leq A_2 < M_2\)
\(0 \leq B_1 < M_1\)
\(0 \leq B_2 < M_2\)
\(0 \leq C_1 < M_1\)
\(0 \leq C_2 < M_2\)
\(0 \leq X_1 < M_1\)
\(0 \leq X_2 < M_1\)
\(0 \leq Y_1 < M_2\)
\(0 \leq Y_2 < M_2\)
\(1 \leq M_1 \leq 10^9\)
\(1 \leq M_2 \leq 10^9\)
输出描述:
You should output lines. Each line contains an integer means the median.
样例输入
5
3 1 4 1 5 9
2 7 1 8 2 9
样例输出
3
4
5
4
5
说明
L = [3, 2 ,4, 1, 7]
R = [4, 8, 8, 3, 9]
题意
给你一个空序列,\(n\)条指令,每次给你\(l,r\) ,表示向序列中加入\(l,l+1,\cdots,r\) 总共\(r-l+1\)个元素,每条指令后输入序列的中位数。
\(n\)条指令按题目所给的方法生成。
题解
这题如果不用离散的话,直接上权值线段树,这里着重讲一下离散的问题。
离散时我开始觉得很不能理解的地方:
什么时候左闭右开
什么时候右端点+1
什么时候右端点-1
我们不妨先来想一组数据:插入\((1,1) \ \ (1,5) \ \ (5,5)\)
如果按照普通离散是不是离散后就是\((1,1) \ \ (1,2) \ \ (2,2)\)
再用普通线段树,那么会发现\((1,1)+(2,2)\)和\((1,2)\)效果一样,也就是中间的点没了,为什么呢?
就是因为离散后我们没法判断某个点是左端点还是右端点还是中间点,导致两点间隙无法判断。
我的处理方法:
- 将离散的点连起来变成求线段长度,比如求\((1,5)\)改成求\((1,6)\)这条线段的长度\((\)都是\(5)\)
- 线段树每个节点\((l,r)\),实际管理区间是\((l,r+1)\)
- 加入线段时,记得右端-1,因为线段树会往右多管理一个点
这样\((1,1) \ \ (1,5) \ \ (5,5)\) 就变成了\((1,2)\ \ (1,6)\ \ (5,6)\),离散后再变成\((1,2)\ \ (1,4) \ \ (3,4)\),记得加入时右端点-1,即\((1,1)\ \ (1,3)\ \ (3,3)\)这几个区间权值+1。
\(ps:\) 这种区间覆盖问题很多都是要考虑端点的问题。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x7f7f7f7f
#define N 800050
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
ll n,num;
ll X[N],Y[N],kth[N];
struct Query{ll l,r;}que[N];
struct Tree{ll l,r,lazy,sum;}tr[N<<2];
void push_up(ll x)
{
ll len=kth[tr[x].r+1]-kth[tr[x].l];
if (tr[x].l==tr[x].r)tr[x].sum=0;
else tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;
tr[x].sum+=tr[x].lazy*len;
}
void push_down(ll x)
{
Tree &a=tr[x<<1],&b=tr[x<<1|1];
a.lazy+=tr[x].lazy;
b.lazy+=tr[x].lazy;
tr[x].lazy=0;
push_up(x<<1);
push_up(x<<1|1);
}
void bt(ll x,ll l,ll r)
{
tr[x].lazy=tr[x].sum=0; tr[x].l=l; tr[x].r=r;
if (l==r)return;
ll mid=(l+r)>>1;
bt(x<<1,l,mid);
bt(x<<1|1,mid+1,r);
}
void change(ll x,ll l,ll r)
{
if (l<=tr[x].l&&tr[x].r<=r)
{tr[x].lazy++;push_up(x);return;}
ll mid=(tr[x].l+tr[x].r)>>1;
if (l<=mid)change(x<<1,l,r);
if (mid<r)change(x<<1|1,l,r);
push_up(x);
}
ll query(ll x,ll k)
{
if (tr[x].l==tr[x].r)return kth[tr[x].l]+(k-1)/tr[x].lazy;
push_down(x);
ll ls=tr[x<<1].sum;
if (ls<k)return query(x<<1|1,k-ls);
else return query(x<<1,k);
}
void work()
{
ll A1,B1,C1,A2,B2,C2,M1,M2,sum=0;
read(n);
read(X[1]); read(X[2]); read(A1); read(B1); read(C1); read(M1);
read(Y[1]); read(Y[2]); read(A2); read(B2); read(C2); read(M2);
for(ll i=3;i<=n;i++)X[i]=(A1*X[i-1]+B1*X[i-2]+C1)%M1;
for(ll i=3;i<=n;i++)Y[i]=(A2*Y[i-1]+B2*Y[i-2]+C2)%M2;
for(ll i=1;i<=n;i++)
{
que[i].l=min(X[i],Y[i])+1;
que[i].r=max(X[i],Y[i])+2;
kth[++num]=que[i].l;
kth[++num]=que[i].r;
}
sort(kth+1,kth+num+1);
num=unique(kth+1,kth+num+1)-kth-1;
bt(1,1,num);
for(ll i=1;i<=n;i++)
{
ll l=lower_bound(kth+1,kth+num+1,que[i].l)-kth;
ll r=lower_bound(kth+1,kth+num+1,que[i].r)-kth;
sum+=que[i].r-que[i].l;
change(1,l,r-1);
printf("%lld\n",query(1,(sum+1)/2));
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
work();
}
2019牛客多校第七场E Find the median 权值线段树+离散化的更多相关文章
- 2019牛客多校第七场E Find the median 离散化+线段树维护区间段
Find the median 题意 刚开始集合为空,有n次操作,每次操作往集合里面插入[L[i],R[i]]的值,问每次操作后中位数是多少 分析 由于n比较大,并且数可以达到1e9,我们无法通过权值 ...
- 2019牛客多校第七场H Pair 数位DP
题意:给你一个3个数A, B, C问有多少对pair(i, j),1 <= i <= A, 1 <= j <= B, i AND j > C或 i XOR j < ...
- 2019牛客多校第七场C-Governing sand(线段树+枚举)
Governing sand 题目传送门 解题思路 枚举每一种高度作为最大高度,则需要的最小花费的钱是:砍掉所有比这个高度高的树的所有花费+砍掉比这个高度低的树里最便宜的m棵树的花费,m为高度低的里面 ...
- 2019牛客多校第七场 F Energy stones 树状数组+算贡献转化模拟
Energy stones 题意 有n块石头,每块有初始能量E[i],每秒石头会增长能量L[i],石头的能量上限是C[i],现有m次时刻,每次会把[s[i],t[i]]的石头的能量吸干,问最后得到了多 ...
- 2019牛客多校第八场 F题 Flowers 计算几何+线段树
2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...
- 牛客多校第七场 C Bit Compression 思维
链接:https://www.nowcoder.com/acm/contest/145/C来源:牛客网 A binary string s of length N = 2n is given. You ...
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
- 2019牛客多校第四场 A meeting
链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...
- Find the median(2019年牛客多校第七场E题+左闭右开线段树)
题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...
随机推荐
- 转:关于C++ const 的全面总结
转自:https://www.cnblogs.com/xkfz007/articles/2419518.html 如有侵权请联系博主,立即删除. C++中的const关键字的用法非常灵活,而使用 ...
- 【学习笔记】OI模板整理
CSP2019前夕整理一下模板,顺便供之后使用 0. 非算法内容 0.1. 读入优化 描述: 使用getchar()实现的读入优化. 代码: inline int read() { int x=0; ...
- Spring框架AOP
aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想.AOP底层也是面向对象:只不过面向的不是普通的Object对象,而是特殊的AOP对象 ...
- Wondershare Video Converter Ultimate 注册码 License
这个软件可以直接将DVD iso转换成mp4播放,可以破解,还不错,特地记录 官网下载最新版: https://videoconverter.wondershare.com/gl/video-conv ...
- spring事务配置异常
spring事务配置不回滚spring事务管理配置,一般来说都是可以回滚的,最近在开发的过程中遇到了一个异常不回滚的问题,最终找到了原因,贴出来一下 1.首先这里定义一个接口 在接口中定义几个方法 2 ...
- Ryu控制器安装部署和入门
Ryu官网简介,原滋原味 Ryu is a component-based software defined networking framework. Ryu provides software c ...
- 第04组 Beta冲刺(1)
队名:斗地组 组长博客:地址 作业博客:Beta冲刺(1/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.分配展示任务 2.收集各个组员的进度 3.写博客 展示GitHub当日代码/文档 ...
- electron之打包成安装程序
1.安装electron-winstaller npm install --save-dev electron-winstaller 2.创建一个build.js var electronInstal ...
- 《maven实战》笔记(1)----maven的初识
刚入职公司用maven进行项目管理,于是昨天下午开始看<maven实战>的pdf,感觉很好,作者写的很有条理. 下面是笔记,看书做笔记还是很有必要的,加强自己的总结. 什么是maven? ...
- Oracle 的 oracle 数据库分类
一.数据库分类 1.小型数据库:access.foxbase 2.中型数据库:informix.sql server.mysql 3.大型数据库:sybase.db2.oracle 二.项目中如何合理 ...