test20190925 老L
100+0+0=100。概率题套路见的太少了,做题策略不是最优的。
排列
给出 n 个二元组,第 i 个二元组为(ai,bi)。
将 n 个二元组按照一定顺序排成一列,可以得到一个排列。显然,这样的排列有 n!种。
我们定义一个排列为坏的的排列,当且仅当这个排列的二元组的第一个元素单调不减或者第二个元素单调不减。
定义一个好的排列为一个非坏排列
如: (1,3) (3,3) (2,2)是一个好排列,(1,1) (2,2) (3,3)是一个坏排列。
请问给出的二元组能构成多少种不同的好排列。由于答案过大,请对 998244353 取膜。
对于 100%的数据 1<=ai,bi<=n<=3e5
题解
容斥一下就完了。时间复杂度 \(O(n \log n)\)。
co int N=300000+10;
int fac[N];
struct node {int x,y;}p[N];
il bool cmp_x(co node&a,co node&b){
return a.x<b.x;
}
il bool cmp_y(co node&a,co node&b){
return a.y<b.y or (a.y==b.y and a.x<b.x);
}
int main(){
freopen("per.in","r",stdin),freopen("per.out","w",stdout);
int n=read<int>();
fac[0]=1;
for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
for(int i=1;i<=n;++i) read(p[i].x),read(p[i].y);
int ans=fac[n];
sort(p+1,p+n+1,cmp_x);
// cerr<<"ans="<<ans<<endl;
int sum=1;
for(int i=1,j=0;i<=n+1;++i)
if(p[i].x!=p[j].x) sum=mul(sum,fac[i-j]),j=i;
ans=add(ans,mod-sum);
// cerr<<"sum="<<sum<<endl;
sort(p+1,p+n+1,cmp_y);
sum=1;
for(int i=1,j=0;i<=n+1;++i)
if(p[i].y!=p[j].y) sum=mul(sum,fac[i-j]),j=i;
ans=add(ans,mod-sum);
// cerr<<"sum="<<sum<<endl;
sum=1;
for(int i=2;i<=n;++i)
if(p[i].x < p[i-1].x) {sum=0;break;}
if(sum)for(int i=1,j=0;i<=n+1;++i){
if(p[i].y!=p[j].y or p[i].x!=p[j].x) sum=mul(sum,fac[i-j]),j=i;
}
ans=add(ans,sum);
// cerr<<"sum="<<sum<<endl;
printf("%d\n",ans);
return 0;
}
中档题
n 个人参加比赛,比赛方式如下:
- 两两比一场,比赛后将每个选手看做一个点,若 i 赢了 j 则连边 i->j
- 将图中强连通分量内继续比,即上一步操作中强连通分量内的所有选手递归进行 1,2,直到每个强连通分量大小为 1。
i<j 时 i 有 a/b 的概率赢 j,问每个人比赛的场数的总和的期望,答案对 998244353 取模
对于 100%的数据 1<=n<=2000,1<=a,b<=100,0<a/b<1
CF913F Strongly Connected Tournament
答案只和点数有关,设\(dp_n\)表示\(n\)个点游戏总场次的期望,\(dp_0=dp_1=0\)。对于有向完全图,一定有且仅有一个入度为0的强连通分量,据此转移。(入度为\(0\)也行)
\]
- 首先选择\(i\)个点形成强连通分量,设\(scc_i\)表示\(i\)个点形成强连通分量的概率。
- 然后这\(i\)个点必须是出度为\(0\)的强连通分量(拓扑序最后一个),换句话说必须被所有其它\(n-i\)个点打败。设\(cw_{n,i}\)表示\(n\)个点中选\(i\)个点满足它们都打败了其它\(n-i\)个点的概率。
- 假设确定了最后一个强连通分量是\(i\)个点,那么这\(i\)个点进行了一轮游戏\(\frac{i(i-1)}{2}\),然后这\(i\)个点进入下一轮\(dp_i\),其它\(n-i\)个点视为正常继续游戏\(dp_{n-i}\),本轮游戏相互之间还有\(i(n-i)\)场。
移项解方程即可。
接下来计算\(cw_{n,i}\)表示\(n\)个点中选\(i\)个点满足它们都打败了其它\(n-i\)个点的概率。
显然\(cw_{n,0}=1\)。打败的概率和编号密切相关,所以通过依赖于点\(n\)的归属来计算:
\]
第\(n\)个点要么是集合中的点,要么是集合外的点。
接下来计算\(scc_n\)表示\(n\)个点形成强连通分量的概率,显然\(s_1=1\)。直接算形成强连通分量相当困难,考虑容斥,用图论套路枚举\(1\)所在SCC大小进行计算。
\]
复杂度\(O(n^2)\)。
co int N=2000+10;
int pp[N],pq[N];
int cw[N][N],scc[N],dp[N];
int main(){
freopen("medium.in","r",stdin),freopen("medium.out","w",stdout);
int n=read<int>(),a=read<int>(),b=read<int>();
int p=mul(a,fpow(b,mod-2)),q=add(1,mod-p);
pp[0]=pq[0]=1;
for(int i=1;i<=n;++i)
pp[i]=mul(pp[i-1],p),pq[i]=mul(pq[i-1],q);
// cerr<<"pp="<<pp[n]<<" pq="<<pq[n]<<endl;
cw[0][0]=1;
for(int s=1;s<=n;++s){
cw[s][0]=1;
for(int i=1;i<=s;++i)
cw[s][i]=add(mul(pp[i],cw[s-1][i]),mul(pq[s-i],cw[s-1][i-1]));
}
// cerr<<"cw="<<cw[n][n/2]<<endl;
for(int s=1;s<=n;++s){
scc[s]=1;
for(int i=0;i<s-1;++i)
scc[s]=add(scc[s],mod-mul(scc[i+1],cw[s][i+1]));
}
// cerr<<"scc="<<scc[n]<<endl;
for(int s=2;s<=n;++s){
int sum=0;
for(int i=1;i<s;++i)
sum=add(sum,mul(scc[i],mul(cw[s][i],add(dp[i],add(dp[s-i],add(i*(s-i),i*(i-1)/2))))));
sum=add(sum,mul(scc[s],s*(s-1)/2));
dp[s]=mul(sum,fpow(add(1,mod-scc[s]),mod-2));
}
printf("%d\n",dp[n]);
return 0;
}
简单题
给些俄罗斯套娃,每个套娃有一个 in,一个 out,in 表示里面空腔的大小,out 表示整体大小,out-in就是套娃厚度,out[i]<=in[j]时 i 可以放进 j,给 n 个套娃,问满足条件的组合有多少种。
- 是内外嵌套的一套(该组合只能有一个最外层的套娃)
- 足够大,这一套不能放进其他套娃里,也就是这一套最外层的 out 要大于所有的 in;
- 空气的体积之和最小。
对于 100%的数据 1<=n<=2e5
CF1197E Culture Code
每个套娃建一个点,每一个套娃向可以套上的套娃连边,建立源点汇点跑最短路条数。
考虑优化建边,将每个点拆成一个 in 和一个 out,只有通过同时两个点才表示选了这一个套娃。
相邻的 out 点大的向小的连边,源汇点向可能作为起点和终点的点连边。
最后形成的图一定是个 DAG,所以可以用拓扑排序求最短路计数。注意一开始需要把所有度数为0的点入队,虽然它们不会造成贡献,但是需要它们来维护拓扑序。
co int N=200000+10;
struct node{int out,in;}a[N];
il bool operator<(co node&a,co node&b){
return a.out<b.out or (a.out==b.out and a.in<b.in);
}
vector<int> to[N*2],we[N*2];
bool vis[N*2];
co int mod=1000000000+7;
int deg[N*2],dis[N*2],cnt[N*2];
deque<int> Q;
il void add_edge(int x,int y,int w){
// cerr<<"add "<<x<<" "<<y<<" w="<<w<<endl;
to[x].push_back(y),we[x].push_back(w),++deg[y];
}
int main(){
freopen("easy.in","r",stdin),freopen("easy.out","w",stdout);
int n=read<int>();
for(int i=1;i<=n;++i) read(a[i].out),read(a[i].in);
sort(a+1,a+n+1);
int s=2*n+1,t=2*n+2;
for(int i=2;i<=n;++i) add_edge(2*i-1,2*i-3,0);
for(int i=1;i<=n;++i) add_edge(2*i-1,2*i,-a[i].out);
for(int i=1;i<=n;++i){
int l=0,r=n;
while(l<r){
int mid=(l+r+1)>>1;
if(a[mid].out<=a[i].in) l=mid;
else r=mid-1;
}
if(l) add_edge(2*i,2*l-1,a[i].in),vis[2*i]=vis[2*l-1]=1;
}
for(int i=1;i<=n;++i)
if(!vis[2*i]) add_edge(2*i,t,a[i].in);
for(int i=n;i>=1;--i){
if(vis[2*i-1]) break;
add_edge(s,2*i,0);
}
fill(dis+1,dis+t+1,1e9);
dis[s]=0,cnt[s]=1;
for(int i=1;i<=t;++i)
if(!deg[i]) Q.push_back(i);
while(Q.size()){
int x=Q.front();Q.pop_front();
for(int i=0;i<(int)to[x].size();++i){
int y=to[x][i],w=we[x][i];
if(dis[y]>dis[x]+w) dis[y]=dis[x]+w,cnt[y]=cnt[x];
else if(dis[y]==dis[x]+w) cnt[y]=(cnt[y]+cnt[x])%mod;
if(--deg[y]==0) Q.push_back(y);
}
}
// cerr<<"check"<<endl;
// for(int i=1;i<=t;++i)
// cerr<<i<<" dis="<<dis[i]<<" cnt="<<cnt[i]<<endl;
printf("%d\n",cnt[t]);
return 0;
}
test20190925 老L的更多相关文章
- test20190924 老L
80+50+100=230.T1没做出来说明我数列学得不好? LOLO 的含树 现有函数 \[ g_m(i)=\begin{cases} 0, & 0 \leq i \leq m\\ i-1+ ...
- 铜齿铁牙UP计划
铜齿铁牙UP计划 我在""做教练"之好声音训练"给出了老师.播音主持学习者,声乐学习者科学用声三要点: 用气发声 共鸣发声 虚实结合 用气发声首先要学会腹式呼吸 ...
- ThinkPHP 汉字转成多种形式拼音
模型: <?php namespace Admin\Model; use Think\Model; /** * 汉字转拼音 * @author huangguojin */ class ZHMo ...
- 这些O2O比你们更靠谱儿
本文纯属虚构,如有雷同,全是 C2C(Copy to China). 一 「什么社区 O2O,不就是跑腿儿的?那叮*小区不好好跑腿儿,非要搞什么狗屁社交,不是死了?」 三十四岁的老刘咽了口唾沫,接着跟 ...
- vue 获取汉字的全拼、简拼、首拼
1.封装公共方法,获取汉字的全拼.简拼.首拼 export const Pinyin = { _JMcode:{ "-":"", "—":& ...
- JavaWeb 后端 <二> 之 Servlet 学习笔记
一.Servlet概述 1.什么是Servlet Servlet是一个运行在服务器端的Java小程序,通过HTTP协议用于接收来自客户端请求,并发出响应. 2.Servlet中的方法 public v ...
- HTML5 3D 粒子波浪动画特效DEMO演示
需要thress.js插件: http://github.com/mrdoob/three.js // three.js - http://github.com/mrdoob/three.js ...
- (l老陈-小石头)典型用户、用户故事、用例图
一.典型用户 老陈 小石头 二.用户故事 老陈:作为一个家长,我希望能利用软件在电脑上储存一些数学题目,以便在繁忙的工作中也能帮助到孩子提高数学. 小石头:作为一个小学二年级的小学生,我希望能利用软件 ...
- “不给力啊,老湿!”:RSA加密与破解
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 加密和解密是自古就有技术了.经常看到侦探电影的桥段,勇敢又机智的主角,拿着一长串毫 ...
随机推荐
- Oracle中恢复drop掉的表中的数据
今天同事不小心把生产上的一张表直接drop掉了,没有做备份,哥们慌的一匹,来找我这个小白来帮忙解决,于是心血来潮简单总结一下. 其实在oralce中,用drop删掉一张表,其实不会真正的删除,只是把表 ...
- 【剑指offer】1+….+n,不能使用相关关键字
题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 分析:可以使用递归! class Soluti ...
- Java生产消费者模型——代码解析
我们将生产者.消费者.库存.和调用线程的主函数分别写进四个类中,通过抢夺非线程安全的数据集合来直观的表达在进行生产消费者模型的过程中可能出现的问题与解决办法. 我们假设有一个生产者,两个消费者来共同抢 ...
- xe.10.2的下载路径
为了这个玩意,我折腾了一天,为了以后自己还用到 官网地址: http://altd.embarcadero.com/download/radstudio/10.2/delphicbuilder10_2 ...
- Python知识之 方法与函数、偏函数、轮询和长轮询、流量削峰、乐观锁与悲观锁
方法与函数 函数需要手动传参self.cls,方法自动传,比如对象方法自动传self,类方法自动传cls,而函数相对而言需要手动传,比如静态绑定的函数,self是需要手动传值得,比如我们平常使用的函数 ...
- Python之路【第十八篇】:前端HTML
一.前端概述 import socket def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind( ...
- android studio下 library打包文件(.aar)和本地引用
关键点: 利用Gradle发布本地maven库支持android library 打包文件(*.aar) 的本地引用 开发环境: windows7 64位操作系统 android studio0.5. ...
- laravel 自定义验证 Validator::extend
laravel 自定义验证 $messages = [ 'name.integer' => '名字不能为整型', 'name.max' => '长度不能超过5', ]; public st ...
- Redis 多级缓存架构和数据库与缓存双写不一致问题
采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构 时效性要求非常高的数据:库存 一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存 ...
- @PropertySouce注解 读取 properties文件
https://www.cnblogs.com/whx7762/p/7885735.html 1.@ProtertySource @PropertySouce是spring3.1开始引入的基于java ...