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_JUDGEfreopen("aa.in","r",stdin);
#endifwork();
}

转载于:https://www.cnblogs.com/mmmqqdd/p/11514991.html

2019牛客多校第七场E Find the median 权值线段树+离散化相关推荐

  1. 2019牛客多校 第七场 B Irreducible Polynomial 多项式因式分解判断

    链接:https://ac.nowcoder.com/acm/contest/887/B 来源:牛客网 Irreducible Polynomial 时间限制:C/C++ 1秒,其他语言2秒 空间限制 ...

  2. 2019牛客多校第七场 C Governing sand

    因为当时时间不怎么够就没写... 其实就是一个模拟题而已下面注释很清楚 链接:https://ac.nowcoder.com/acm/contest/887/C 来源:牛客网 时间限制:C/C++ 3 ...

  3. 【牛客 - 157C】PH试纸(前缀和,或权值线段树,主席树)

    题干: 链接:https://ac.nowcoder.com/acm/contest/157/C 来源:牛客网 题目描述 PH试纸,是一种检测酸碱度的试纸,试纸红色为酸性,蓝色为碱性. HtBest有 ...

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

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

  5. 2019暑期训练——牛客第七场 C. Governing sand(权值线段树)

    Governing sand 链接: https://ac.nowcoder.com/acm/contest/887/C 题意: 给n种树,其中每一种树都有高度h,每砍掉一棵树所需要的代价c,这种树的 ...

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

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

  7. 2019牛客多校训练营第一场 H题 HOR 题解

    题目描述: 输入描述: 输出描述: 示例1: 题解: 更多问题可关注牛客竞赛区,一个刷题.比赛.分享的社区. 传送门:https://ac.nowcoder.com/acm/contest/discu ...

  8. 2019牛客多校训练营第一场 E题 ABBA 题解

    问题描述: 输入描述: 输出描述: 示例1: 题解: 更多问题可关注牛客竞赛区,一个刷题.比赛.分享的社区. 传送门:https://ac.nowcoder.com/acm/contest/discu ...

  9. 2019牛客多校第四场 B xor (线性基求交)

    xor 思路 题目是要求[l,r][l, r][l,r]的所有集合是否都可以得到xxx,那么显然我们可以对这[l,r][l, r][l,r]个线性基求交,然后再特判能否xxx能否插入,如果能插入,显然 ...

最新文章

  1. JS中的作用域(一)-详谈
  2. cve-2015-0569 安卓手机提权ROOT漏洞 分析
  3. 【重磅】央行发大招!最全面的支付安全风险大检查来了……
  4. 2018/Province_Java_A/2/星期一
  5. rabbitmq 消费端代码获取队列名称_C#调用RabbitMQ实现消息队列的示例代码
  6. python判断密码强度_python实现密码强度校验
  7. c++ new 数组_用Java实现JVM第八章《数组和字符串》
  8. java中四种修饰符
  9. 网页中怎样制作虚线表格
  10. VISTA三步共享文件夹
  11. oracle 比较日期相等
  12. Linux操作系统常用基本命令
  13. spring调用webservice
  14. 用python在大麦网抢票_大麦网抢票python+selenium实现
  15. js树结构数据的递归操作
  16. 关于MySQL8的URL和Driver的写法
  17. linux 端口不通,linux的端口不通怎么解决
  18. 不断突破道,用道来挣钱才能长稳,才能心安!
  19. 1.7 使用不同设备类型的iOS模拟器 [原创iOS开发-Xcode教程]
  20. 无法打开到主机的连接。 在端口 23: 连接失败

热门文章

  1. 【Python 必会技巧】使用 Python 追加写入 json 文件或更改 json 文件中的值
  2. 【Python CheckiO 题解】Create Intervals
  3. java tostring 库_java重寫toString()方法
  4. 【CSU - 1023】【HRBUST - 1039】修路(二分,枚举)
  5. 【sdut 1751】 区间覆盖问题
  6. 5, Data Augmentation
  7. c语言程序设计现代方法快速排序,C语言实现快速排序改进版
  8. 限制 计算机中 某用户上网 win7,利用win7限制上网时间的方法
  9. linux系统键盘记录器,可截获到 QQ 密码 键盘记录器源码
  10. 摩托罗拉为什么要限制自家linux手机,摩托罗拉为何在安卓手机大放异彩的时候,突然开始衰败了呢?...