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/C++语言之由数字26引起的文件的数据保存与读取调试。
首先在VS2010中遇到的问题是,建立了一个结构体 struct position{ int x; int y; }: 然后用此结构体声明一个数组rout[8]; for(int i=0;i<8 ...
- 删除git中无用的大文件
推荐阅读:为什么你的 Git 仓库变得如此臃肿 有时候我们不小心提交了一些大文件上去,后来删除了,但是已经于事无补了,整个git的提及已经蹭蹭上去了. 这个时候怎么办呢? 1. 查看有哪些大文件(to ...
- 面试题_Spring高级篇
Spring高级篇 1.什么是 Spring 框架? Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发提供了综合.广泛的基础性支持的 Java 平台. Spr ...
- Ryu控制器安装部署和入门
Ryu官网简介,原滋原味 Ryu is a component-based software defined networking framework. Ryu provides software c ...
- Maven的概述和基础(学习整理)
1. Maven是啥 Maven是一个项目管理工具,包含了一个项目对象模型(POM),一组标准集合,一个项目生命周期(Lifecycle),一个依赖管理系统,和用来运行定义在生命周期阶段中的插件目标的 ...
- P1944 最长括号匹配_NOI导刊2009提高(1)
P1944 最长括号匹配_NOI导刊2009提高 题解 宁愿相信世上有鬼,也不能随便相信某谷题目标签 我想了半天然后看了眼题解,发现用栈来模拟就好了 栈来模拟,还要用到一个bool数组,标记是否已经匹 ...
- linux下的什么工具可以用来查看PostScript文件?
答: ghostview,官网在这里
- AnimationDrawable
①先定义一个AnimationDrawable的xml资源文件: <?xml version="1.0" encoding="utf-8"?> &l ...
- 001-多线程-JUC集合-框架概述
一.概述 1.1.java集合 java集合的架构,主体内容包括Collection集合和Map类:而Collection集合又可以划分为List(队列)和Set(集合). 1. List的实现类主要 ...
- CentOS7 升级 python3 过程及注意
• 从官网下载python3的压缩包,解压(以3.5.1版本为例)• 创建安装目录(自定义)sudo mkdir /usr/local/python3• cd 进入解压目录sudo ./configu ...