文章目录

  • [Poi2014]Couriers
    • problem
    • solution
    • code
  • CodeChef - TKCONVEX
    • problem
    • solution
    • code

随机算法的典型套路:枚举太花时,转化为随机一个数。然后通过对正确率的分析,选择一个随机的次数来卡。前提是要保证每一次检验随机是否为答案的时间复杂度要能够接受。一般不超过 nlog⁡nn\log nnlogn。

[Poi2014]Couriers

problem

BZOJ 3524

solution

如果有解,也就是说区间内的随机选择一个数是答案的概率不大于 12\frac 1 221​。否则怎么随机都无解。

可以预处理相同值的数出现位置,二分查找求出某个值在 [l,r][l,r][l,r] 区间的出现次数。

所以一次判断是 O(log⁡n)O(\log n)O(logn) 的。

随机 202020 次,正确率就在 1−10−51-10^{-5}1−10−5 左右了。

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 500005
int n, m;
int a[maxn];
vector < int > pos[maxn];int find_l( int x, int p ) { int l = 0, r = pos[x].size() - 1, ans;while( l <= r ) {int mid = l + r >> 1;if( pos[x][mid] >= p ) ans = mid, r = mid - 1;else l = mid + 1;}return ans;
}int find_r( int x, int p ) {int l = 0, r = pos[x].size() - 1, ans;while( l <= r ) {int mid = l + r >> 1;if( pos[x][mid] <= p ) ans = mid, l = mid + 1;else r = mid - 1;}return ans;
}int main() {scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ ) {scanf( "%d", &a[i] );pos[a[i]].push_back( i );}mt19937 wwl(time(0));for( int i = 1, l, r;i <= m;i ++ ) {scanf( "%d %d", &l, &r );uniform_int_distribution < int > range( l, r );for( int k = 1;k <= 20;k ++ ) {int x = range( wwl ); x = a[x];int L = find_l( x, l );int R = find_r( x, r );if( R - L + 1 << 1 > r - l + 1 ) { printf( "%d\n", x ); goto next_turn; }}printf( "0\n" );next_turn:;}return 0;
}

CodeChef - TKCONVEX

problem

vjudge链接

solution

定理1 能构成多边形的线段,必须满足任意一条边长度都小于剩余所有边长度的总和。

这是显然的,因为要形成封闭的图形,可以看作是这条边是最后一条连接两个端点的直线段,其余线段绕成了一个弧形。

事实上只需要长度最长的线段满足这个性质即可。

此定理只能保证构成多边形,但不保证是凸多边形。所以提出下一个定理。

定理2 任意非凸多边形都可以通过对边的旋转和平移构成一个新凸多边形。

在本题中,可以选择的集合为 (n2k)(2kk)\binom{n}{2k}\binom{2k}{k}(2kn​)(k2k​),已经是非常大了,不可能一个一个检验。

定理3 假设有解,那么一定存在一个解(大小为 kkk 的子集)满足:对所有线段长度排序后,这个子集的元素对应排序后序列的一段连续区间。

证明:显然。假设子集为 SSS,排序后的序列为 PPP。

如果其对应的元素构成不连续的区间。即 ∃iPi∈S∧Pi+1∉S\exist_iP_i\in S\wedge P_{i+1}\notin S∃i​Pi​∈S∧Pi+1​∈/​S。

找到满足条件的 iii,则 iii 肯定是一段连续区间的右端点,保证 iii 不是若干个不连续区间的最右端点。

重复操作移除 PiP_iPi​,加入 Pi+1P_{i+1}Pi+1​。直到将左边的若干个不连续区间和最右边的一个连续区间拼接成一整个大连续区间。

这样操作后,可以发现长度最大的依然是最右边的端点,没有移动过,但是其余线段的长度都有所增长。

既然原来都是符合条件的子集,那么现在肯定也是一个符合条件的子集。

题目要求两个大小为 kkk 的凸多边形。

不妨设第一个凸多边形从边集合为 SSS 中,选择另一个凸多边形从边集合 Sˉ\bar{S}Sˉ 中选择。

满足 S⋂Sˉ=∅∧S⋃Sˉ=ΩS\bigcap\bar{S}=\empty\wedge S\bigcup \bar{S}=\OmegaS⋂Sˉ=∅∧S⋃Sˉ=Ω。

那么对于每一条线段,有 12\frac 1 221​ 的概率属于 SSS,12\frac 1 221​ 的概率属于 Sˉ\bar{S}Sˉ。换言之,选出任意一个子集的概率是相同的。

那么就对每条边随机其属于哪个集合。

随机划分集合后,O(n)O(n)O(n) 的可以做到快速判断这个集合能否选出一个子集构成凸多边形。

最后来分析一下这个随机的正确率。

划分的总方案数为 2n2^n2n。考虑极端最坏情况,有且仅有两个互不相交的集合 X,YX,YX,Y 可以构成凸多边形。

那么一个随机划分方案有解,当且仅当 S⋂X=X∧S⋂Y=∅S\bigcap X=X\wedge S\bigcap Y=\emptyS⋂X=X∧S⋂Y=∅ 或者 S⋂Y=Y∧S⋂X=∅S\bigcap Y=Y\wedge S\bigcap X=\emptyS⋂Y=Y∧S⋂X=∅。

这样的方案数为 2n−2k×22^{n-2k}\times 22n−2k×2。

因此在最坏情况下选出一个合法划分的概率为 122k−1\frac{1}{2^{2k-1}}22k−11​。

设随机运行以上算法 ttt 次,那么 ttt 最多取到 200002000020000 左右,时间复杂度为 O(nlog⁡n+tn)O(n\log n+tn)O(nlogn+tn)。

在 k=6k=6k=6 时,正确率为 1−(1−1211)t≈1−10−51-(1-\frac{1}{2^{11}})^t≈1-10^{-5}1−(1−2111​)t≈1−10−5。

注意:原题目 k∈[3,10]k\in[3,10]k∈[3,10]。这个随机算法是不能通过的。所以下面的代码不保证正确性。

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
#define int long long
struct node { int val, id; }a[maxn];
int n, k;
int s[2][maxn];
pair < int, int > ans[2];signed main() {scanf( "%lld %lld", &n, &k );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i].val ), a[i].id = i;sort( a + 1, a + n + 1, []( node x, node y ) { return x.val < y.val; } );mt19937 wwl;uniform_int_distribution < int > range( 0, 1 );for( int t = 1;t <= 20000;t ++ ) {s[0][0] = s[1][0] = 0;for( int i = 1;i <= n;i ++ ) {int x = range( wwl );s[x][++ s[x][0]] = i;}int cnt = 0;for( int j = 0;j <= 1;j ++ ) {for( int i = 1, len = 0, sum = 0;i <= s[j][0];i ++ ) {len ++, sum += a[s[j][i]].val;if( len > k ) sum -= a[s[j][i - k]].val;if( len == k and sum > (a[s[j][i]].val << 1) ) {ans[j] = make_pair( i - k + 1, i );cnt ++;break;}}}if( cnt == 2 ) goto yes;}no : return ! printf( "No\n" );yes :printf( "Yes\n" );for( int i = 0;i <= 1;i ++ )for( int j = ans[i].first;j <= ans[i].second;j ++ )printf( "%lld ", a[s[i][j]].id );return 0;
}

[骗分技巧——随机化Ⅱ] [Poi2014]Couriers,CodeChef - TKCONVEX相关推荐

  1. [骗分技巧——随机化Ⅰ]CodeChef-Milestones,CF364D-Ghd

    文章目录 CodeChef-Milestones problem solution code CF364D-Ghd problem solution code 设随机化一次的正确率为 ppp,一次的复 ...

  2. 新版骗分导论 - 第7 版

    新版骗分导论第7版\quad\tiny\texttt{第 7 版}第 7 版 修订--Jerrycyx(CSDN,洛谷) 洛谷博客查看 前言 这是我在倒腾洛谷水贴时偶然翻到的一篇博客,自认为写得很好, ...

  3. 大神cyd的骗分导论

    新 版 骗 分 导 论 THE NEW GUIDE OF CHEATING IN INFORMATICS OLYMPIAD 蒟 蒻 的 宝 书 目录 第1章 绪论 第2章 从无解出发 2.1 无解情况 ...

  4. 新 版 骗 分 导 论

    新 版 骗 分 导 论{蒟 蒻 的 宝 书} {目 录} 第1章 绪论 第2章 从无解出发 ↪ 2.1 无解情况 ↪ 2.2 样例--白送的分数 第3章 "艰苦朴素永不忘" ↪ 3 ...

  5. 新版骗分导论(最少骗到省级三等奖)

    第1章 绪论 在Oier中,有一句话广为流传: t{任何蒟蒻必须经过大量的刷题练习才能成为大牛乃至于神牛}任何蒟蒻必须经过大量的刷题练习才能成为大牛乃至于神牛≺ 这就是著名的lzn定理.然而,我们这些 ...

  6. 骗分导论-第8修订测试版

    参考:<骗分导论-第7修订测试版><骗分导论-第6修订测试版><骗分导论-第5修订测试版><骗分导论-第4修订测试版><骗分导论-第3修订测试版& ...

  7. C++考试题目骗分秘籍

    应用在什么情况(前言) 如果考试时间只有15分钟了,你还有3道题没写,或者是实在不会做,那该怎么办??? 答案只有三条: 1.放弃 2.骗分 3.拼命想出来 显然只有2,3可选,所以还剩好多时间的话( ...

  8. “ 骗 ”分指南——对于蓝桥你不得不知的应试技巧(文末发送礼包)

    文章目录 前言 合理使用考试外的电脑工具--简称外挂 计算器 excel 常用的代码模板 辗转相除法求最大公约数 闰年 素数 排序--sort 函数库 暴力 万能钥匙--DFS 打表 最后 前言 蓝桥 ...

  9. CV入门赛最全思路上分技巧汇总!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:安晟,算法工程师,Datawhale成员 赛题数据及背景 http ...

最新文章

  1. 设计模式之解释器模式(Interpreter)摘录
  2. SQL:EXISTS的用法理解(转)
  3. “习惯性思维”引起的血案
  4. javaMe开发按钮
  5. React之事件绑定
  6. 【软件项目管理】知识点整理
  7. python动态创建字典_如何在Python中创建动态命名字典?
  8. 《ISO20000-12011 认证合格判定基础》(证书样例子+认证文档+录音下载)
  9. vivo android 刷机教程,vivo Xshot升级Android 4.4刷机教程
  10. 一、C++反作弊对抗实战 (基础篇 —— 4.利用消息钩子注入DLL)
  11. 微信公众平台开发 整合百度云开放平台与微信开放平台
  12. 一台电脑有几个计算机用户账户,多人共用一台电脑设置多个使用账户的方法
  13. 推荐术语:CPM、CPC、CPA、CPI、CTR、CPV、CVR
  14. 简述docx文档格式-CTF竞赛专用
  15. win10锁定计算机后黑屏,win10电脑突然黑屏无法唤醒怎么办?老司机告诉你解决方法...
  16. 海康视频插件启动过程中出现跨域问题has been blocked by CORS policy
  17. 解决:Jackson反序列化Java内部类失败(序列化后的识别码为LinkedHashMap,而非内部类本身)
  18. WIN10设置自启动脚本
  19. python 中文乱码问题
  20. 信号完整性分析5——信号上升时间

热门文章

  1. linux安装定制添加输入,Arch Linux--定制自己的Linux操作系統(乙-國際化桌面安裝篇)...
  2. mysql批量条件字段_mysql批量更新多条记录的同一个字段为不同值的方法
  3. linux 逻辑卷 pe size 4.00 mib大小怎么改,linux逻辑卷的建立
  4. 安装linux6.10 I386系统教程,一看就懂的Centos6.10安装教程
  5. java一个界面用另一个界面的值_如何将参数/值从一个弹出窗口传递到Angular2中的另一个弹出窗口...
  6. java file rename 失败_java重命名文件造成文件不可读写
  7. [Spring5]Spring框架概述
  8. [数据结构]树、森林与二叉树之间的相互转换方法
  9. LeetCode 143 重排链表-中等
  10. 蓝桥杯2015初赛-牌型种数-dfs