[计蒜客T2238]礼物_线段树_归并排序_概率期望
礼物
题目大意:
数据范围:
题解:
这题有意思啊($md$卡常
直接做怎么做?
随便上个什么东西,维护一下矩阵乘和插入,比如说常数还算小的$KD-Tree$(反正我是没见人过过
我们漏掉了一个条件,就是所有二元组都是随机的。
这个条件很好,它几乎就保证了,任选一个区间的话,优秀二元组只有$log$个。
这是为什么呢?
其实区间内,优秀二元组的个数,就相当于把区间按照$x$排序后,$y$值是前缀最大值的期望个数。
因为二元组是随机的,所以$x$排序后,$y$仍然是随机的。
就是给定一个随机数列,求前缀最大值的期望个数。
这是调和级数的。
所以,我们就开一棵线段树,线段树上每个节点维护一个数组,存这个节点管辖区间内的优秀二元组。
合并用归并,复杂度是$O(log)$的。
所以每次查询的复杂度是$O(log^2n)$的。
总复杂度是$O(nlog^2n)$的,有点小卡常,加了输出优化才过(读入优化是必备。
代码:
- #include <bits/stdc++.h>
- #define ls p << 1
- #define rs p << 1 | 1
- #define N 200010
- using namespace std;
- const int mod = 1000000007 ;
- typedef long long ll;
- char *p1, *p2, buf[100000];
- #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
- int rd() {
- int x = 0;
- char c = nc();
- while (c < 48) {
- c = nc();
- }
- while (c > 47) {
- x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
- }
- return x;
- }
- char pbuf[100000],*pp=pbuf;
- void push(const char c) {
- if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf;
- *pp++=c;
- }
- void write(int x) {
- static int sta[35];
- int top=0;
- do{sta[top++]=x%10,x/=10;}while(x);
- while(top) push(sta[--top]+'0');
- push('\n');
- }
- struct Node {
- int x, y;
- friend bool operator < (const Node &a, const Node &b) {
- return a.x == b.x ? a.y < b.y : a.x < b.x;
- }
- }num[N];
- Node q[60];
- struct Mode {
- Node v[30];
- int len;
- int sum;
- Mode() { len = 0, sum = 1; }
- }a[N << 2];
- inline Mode operator + (const Mode &a, const Mode &b) {
- Mode re;
- int cnt = 0;
- int j = 1;
- for (int i = 1; i <= a.len; i ++ ) {
- while ((j <= b.len) && (a.v[i] < b.v[j])) {
- q[ ++ cnt] = b.v[j];
- j ++ ;
- }
- q[ ++ cnt] = a.v[i];
- }
- while (j <= b.len) {
- q[ ++ cnt] = b.v[j];
- j ++ ;
- }
- // int i = 1, j = 1;
- // while (i <= a.len && j <= b.len) {
- // if (a.v[i] < b.v[j]) {
- // q[ ++ cnt] = a.v[i];
- // i ++ ;
- // }
- // else {
- // q[ ++ cnt] = b.v[j];
- // j ++ ;
- // }
- // }
- // while (i <= a.len) {
- // q[ ++ cnt] = a.v[i];
- // i ++ ;
- // }
- // while (j <= b.len) {
- // q[ ++ cnt] = b.v[j];
- // j ++ ;
- // }
- // for (int i = 1; i <= a.len; i ++ ) {
- // q[ ++ cnt] = a.v[i];
- // }
- // for (int i = 1; i <= b.len; i ++ ) {
- // q[ ++ cnt] = b.v[i];
- // }
- // sort(q + 1, q + cnt + 1);
- int mx = 0;
- for (int i = 1; i <= cnt; i ++ ) {
- if (q[i].y > mx) {
- re.v[ ++ re.len] = q[i];
- re.sum = (ll)re.sum * (q[i].x ^ q[i].y % mod) % mod;
- mx = q[i].y;
- }
- }
- // reverse(re.v + 1, re.v + re.len + 1);
- return re;
- }
- void build(int l, int r, int p) {
- if (l == r) {
- a[p].v[ ++ a[p].len] = num[l];
- a[p].sum = (num[l].x ^ num[l].y) % mod;
- return;
- }
- int mid = (l + r) >> 1;
- build(l, mid, ls);
- build(mid + 1, r, rs);
- a[p] = a[ls] + a[rs];
- }
- Mode query(int x, int y, int l, int r, int p) {
- if (x <= l && r <= y) {
- return a[p];
- }
- int mid = (l + r) >> 1;
- if (mid < x)
- return query(x, y, mid + 1, r, rs);
- else if(y <= mid)
- return query(x, y, l, mid, ls);
- else
- return query(x, y, l, mid, ls) + query(x, y, mid + 1, r, rs);
- }
- int main() {
- int n = rd();
- for (int i = 1; i <= n; i ++ ) {
- num[i].x = rd();
- num[i].y = rd();
- }
- build(1, n, 1);
- int q = rd();
- while(q -- ) {
- int x = rd(), y = rd();
- Mode now = query(x, y, 1, n, 1);
- write(now.sum);
- }
- fwrite(pbuf,1,pp-pbuf,stdout);
- return 0;
- }
小结:这种期望的题还是要自己证才行,不然结论根本记不过来。
[计蒜客T2238]礼物_线段树_归并排序_概率期望的更多相关文章
- 【原创】tyvj1038 忠诚 & 计蒜客 管家的忠诚 & 线段树(单点更新,区间查询)
最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不懂真的说明最基础的理论没明白 推荐一篇文章http://www.cnblogs.com/liwenchi/ ...
- [计蒜客] 矿石采集【记搜、Tarjan缩点+期望Dp】
Online Judge:计蒜客信息学3月提高组模拟赛 Label:记搜,TarJan缩点,树状数组,期望Dp 题解 整个题目由毫无关联的两个问题组合成: part1 问题:对于每个询问的起点终点,求 ...
- 计蒜客 28315.Excellent Engineers-线段树(单点更新、区间最值) (Benelux Algorithm Programming Contest 2014 Final ACM-ICPC Asia Training League 暑假第一阶段第二场 E)
先写这几道题,比赛的时候有事就只签了个到. 题目传送门 E. Excellent Engineers 传送门 这个题的意思就是如果一个人的r1,r2,r3中的某一个比已存在的人中的小,就把这个人添加到 ...
- 计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛
Max answer Alice has a magic array. She suggests that the value of a interval is equal to the sum of ...
- 计蒜客 41391.query-二维偏序+树状数组(预处理出来满足情况的gcd) (The Preliminary Contest for ICPC Asia Xuzhou 2019 I.) 2019年徐州网络赛)
query Given a permutation pp of length nn, you are asked to answer mm queries, each query can be rep ...
- 计蒜客 Prefix Free Code(字典树+树状数组)
Consider n initial strings of lower case letters, where no initial string is a prefix of any other i ...
- 计蒜客 NOIP 提高组模拟竞赛第一试 补记
计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...
- 计蒜客 28449.算个欧拉函数给大家助助兴-大数的因子个数 (HDU5649.DZY Loves Sorting) ( ACM训练联盟周赛 G)
ACM训练联盟周赛 这一场有几个数据结构的题,但是自己太菜,不会树套树,带插入的区间第K小-替罪羊套函数式线段树, 先立个flag,BZOJ3065: 带插入区间K小值 计蒜客 Zeratul与Xor ...
- 计蒜客 A1607 UVALive 8512 [ACM-ICPC 2017 Asia Xi'an]XOR
ICPC官网题面假的,要下载PDF,点了提交还找不到结果在哪看(我没找到),用VJ交还直接return 0;也能AC 计蒜客题面 这个好 Time limit 3000 ms OS Linux 题目来 ...
随机推荐
- IntelliJ IDEA 创建 Git 分支并且 Push 到远程
在 IntelliJ 的右下角,你可以看到当前的 Git 分支,然后你可以单击这个分支后,在弹出的界面的最上方有一个新建分支的选项. 然后再弹出的界面中,输入你要创建的分支名称后回车输入. 然后从项目 ...
- CentOS7部署tomcat
首先检查是否安装了jdk,然后再查看是否配置了JAVA_HOME 配置JAVA_HOME的方法: 我的是jdk已经安装好了是1.8 我需要找到它的安装目录 [root@bogon xwg]# java ...
- 逻辑回归原理 面试 Logistic Regression
逻辑回归是假设数据服从独立且服从伯努利分布,多用于二分类场景,应用极大似然估计构造损失函数,并使用梯度下降法对参数进行估计.
- git避免提交本地配置文件-来自同事的分享
在项目协作中,对于已经更改的文件,不同的开发者常常需要根据自己的需要对文件进行更改已满足本地开发环境的需求(这种情况很常见,一般是对项目相关的配置项的更改,对业务逻辑代码的更改一般都是正常的协作编码过 ...
- MIME协议(五) -- MIME邮件的编码方式
5 MIME邮件的编码方式 由于每个ASCII码字符只占用一个字节(8个bit位),且最高bit位总为0,即ASCII码字符中的有真正意义的信息只是后面的7个低bit位,而传统的SMTP协议又是基于 ...
- HDU6513/CCPC2017--A Secret(KMP)
A Secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)Total ...
- 使用Spring基于应用层实现读写分离(一)基础版
背景 我们一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,有一个思路就是说采用数据库集群的方案, 其中一个是主库,负责写入数据,我们称之为:写库: 其它都是从库,负责读取数据 ...
- HTTP之简析
1. 简介 HTTP 协议是 Hyper Text Transfer Protocol(超文本传传输协议)的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议.HTTP 通常架构在 TCP 传 ...
- 【软件工程】Alpha事后诸葛亮
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 参考邹欣老师的问题模板进行总结思考 一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的 ...
- LeetCode 最长公共前缀(探索字节跳动)
题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow ...