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. 什么时候左闭右开

  2. 什么时候右端点+1

  3. 什么时候右端点-1

我们不妨先来想一组数据:插入\((1,1) \ \ (1,5) \ \ (5,5)\)

如果按照普通离散是不是离散后就是\((1,1) \ \ (1,2) \ \ (2,2)\)

再用普通线段树,那么会发现\((1,1)+(2,2)\)和\((1,2)\)效果一样,也就是中间的点没了,为什么呢?

就是因为离散后我们没法判断某个点是左端点还是右端点还是中间点,导致两点间隙无法判断。

我的处理方法:

  1. 将离散的点连起来变成求线段长度,比如求\((1,5)\)改成求\((1,6)\)这条线段的长度\((\)都是\(5)\)
  2. 线段树每个节点\((l,r)\),实际管理区间是\((l,r+1)\)
  3. 加入线段时,记得右端-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 权值线段树+离散化的更多相关文章

  1. 2019牛客多校第七场E Find the median 离散化+线段树维护区间段

    Find the median 题意 刚开始集合为空,有n次操作,每次操作往集合里面插入[L[i],R[i]]的值,问每次操作后中位数是多少 分析 由于n比较大,并且数可以达到1e9,我们无法通过权值 ...

  2. 2019牛客多校第七场H Pair 数位DP

    题意:给你一个3个数A, B, C问有多少对pair(i, j),1 <= i <= A, 1 <= j <= B, i AND j > C或 i XOR j < ...

  3. 2019牛客多校第七场C-Governing sand(线段树+枚举)

    Governing sand 题目传送门 解题思路 枚举每一种高度作为最大高度,则需要的最小花费的钱是:砍掉所有比这个高度高的树的所有花费+砍掉比这个高度低的树里最便宜的m棵树的花费,m为高度低的里面 ...

  4. 2019牛客多校第七场 F Energy stones 树状数组+算贡献转化模拟

    Energy stones 题意 有n块石头,每块有初始能量E[i],每秒石头会增长能量L[i],石头的能量上限是C[i],现有m次时刻,每次会把[s[i],t[i]]的石头的能量吸干,问最后得到了多 ...

  5. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  6. 牛客多校第七场 C Bit Compression 思维

    链接:https://www.nowcoder.com/acm/contest/145/C来源:牛客网 A binary string s of length N = 2n is given. You ...

  7. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  8. 2019牛客多校第四场 A meeting

    链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...

  9. Find the median(2019年牛客多校第七场E题+左闭右开线段树)

    题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...

随机推荐

  1. maven+SSM+junit+jetty+log4j2环境配置的最佳实践

    思路大致是 jetty插件 -> junit -> SpringMVC -> Spring -> log4j2 -> Mybatis整合 pom中的依赖跟着思路一批一批的 ...

  2. Flask-CBV模式

    Flask中的CBV模式 ''' flask中的CBV模式: (1)导入views模块: from flask import views (2)定义类,继承views.MethodView类: cla ...

  3. 2015-2016 ACM ICPC Baltic Selection Contest

    这是上礼拜三的训练赛,以前做过一次,这次仅剩B题没补.题目链接:https://vjudge.net/contest/153192#overview. A题,水题. C题,树形DP,其实是一个贪心问题 ...

  4. OpenCV学习笔记(2)——如何用OpenCV处理视频

    如何用OpenCV处理视频 读取视频文件,显示视频,保存视频文件 从摄像头获取并显示视频 1.用摄像头捕获视频 为了获取视频,需要创建一个VideoCapature对象.其参数可以是设备的索引号,也可 ...

  5. Servlet的运行原理

  6. x86架构64位模式下的寄存器列表

    在此列出x86架构处理器在64位模式下的可用寄存器列表,方便查阅- 这里要注意的是,在64位模式下,所有通用寄存器都能访问第8位部分,低16位部分以及低32位部分. 以下是64位模式下AMD64 AB ...

  7. tomcat配置使用log4j管理日志

    从tomcat官网下载和tomcat对应的tomcat-juli.jar和tomcat-juli-adapters.jar,从log4j官网下载log4j的jar包(我用的是log4j-1.2.17. ...

  8. Python简单遍历字典及删除元素的方法

    Python简单遍历字典及删除元素的方法 这篇文章主要介绍了Python简单遍历字典及删除元素的方法,结合实例形式分析了Python遍历字典删除元素的操作方法与相关注意事项,需要的朋友可以参考下 具体 ...

  9. windows下node.js安装配置

    转自 http://www.cnblogs.com/yzadd/p/6547668.html

  10. 二分类Logistic回归模型

    Logistic回归属于概率型的非线性回归,分为二分类和多分类的回归模型.这里只讲二分类. 对于二分类的Logistic回归,因变量y只有“是.否”两个取值,记为1和0.这种值为0/1的二值品质型变量 ...