【题解】Comet OJ Round 70 简要题解
【题解】Comet OJ Round 70 简要题解
A
将放在地上的书按照从小到大排序后,问题的本质就变成了合并两个序列使得字典序最小。可以直接模拟归并排序。直接用循环和std::merge
实现这个过程。复杂度\(O(n)\)
//@winlere
#include<cstdio>
#include<algorithm>
using namespace std;
int data[100003],in[100003],data2[100003],ans[100003],cnt,n,m;
int main(){
scanf("%d%d",&n,&m);
for(int t=1;t<=m;++t) scanf("%d",data+t),in[data[t]]=1;
for(int t=1;t<=n;++t) if(!in[t]) data2[++cnt]=t;
merge(data+1,data+m+1,data2+1,data2+cnt+1,ans+1);
for(int t=1;t<=n;++t) printf("%d\n",ans[t]);
return 0;
}
B
由于题目保证了字符串之间互不为前缀,所以由给定字符串的排名连接而成形成排列的字典序就是这个字符串的字典序。
现在问题就是求出\(\sum|S|\le 1e6\)的这么多字符串的字典序,你若肝的话可以直接上SA,但是更简单的办法是建出一颗Trie树随后在上面DFS。匹配最后那个串的时候也可以直接在Tri树上查询。
现在我们得到了一个排列,问字典序排名第几,直接魔改一下康拓展开即可。复杂度\(O(n\log n)\)
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e6+5;
const int mod=1e9+7;
char c[maxn];
struct NODE{
int son[26],id;
NODE(){}
inline int&operator[](int x){return son[x];}
inline int&operator[](char x){return son[x-'a'];}
}ac[maxn];
int data[maxn],cnt,seg[maxn],jc[maxn],inv[maxn],rk[maxn],n,k,ans=1;
inline void insert(const char*c,const int&len,const int&i){
int now=0;
for(int t=1;t<=len;++t)
ac[now][c[t]]?now=ac[now][c[t]]:now=ac[now][c[t]]=++cnt;
ac[now].id=i;
}
void dfs(const int&now){
if(ac[now].id) rk[ac[now].id]=++*rk;
for(int t=0;t<26;++t) if(ac[now][t]) dfs(ac[now][t]);
}
inline void add(const int&pos,const int&tag){for(int t=pos;t<=n;t+=t&-t) seg[t]+=tag;}
inline int que(const int&pos,int ret=0){
for(int t=pos;t>0;t-=t&-t) ret+=seg[t];
return ret;
}
inline int ksm(const int&base,const int&p,int ret=1){
for(int t=p,b=base;t;t>>=1,b=1ll*b*b%mod) if(t&1) ret=1ll*ret*b%mod;
return ret;
}
inline void pre(const int&n){
jc[0]=inv[0]=1;
for(int t=1;t<=n;++t) jc[t]=1ll*jc[t-1]*t%mod;
inv[n]=ksm(jc[n],mod-2);
for(int t=n-1;t;--t) inv[t]=1ll*inv[t+1]*(t+1)%mod;
}
int main(){
pre(1e6); scanf("%d%d",&n,&k);
for(int t=1;t<=n;++t) scanf("%s",c+1),insert(c,strlen(c+1),t);
dfs(0);
scanf("%s",c+1);
for(int t=1,cur=1,ed=strlen(c+1);t<=ed;t=cur){
int now=0,f=0;
while(!f) now=ac[now][c[cur++]],f=ac[now].id;
data[++*data]=rk[f];
}
for(int t=1;t<=n;++t) add(t,1);
for(int t=1,ed=*data,g;t<=ed;++t)
g=que(data[t]),add(data[t],-1),ans=(ans+1ll*(g-1)*jc[n-t]%mod*inv[n-k])%mod;
printf("%d",ans);
return 0;
}
主办方看起来会让\(O(n^2)\)开O2过是什么鬼...
C
在路上
【题解】Comet OJ Round 70 简要题解的更多相关文章
- Comet OJ - Contest #2 简要题解
Comet OJ - Contest #2 简要题解 cometoj A 模拟,复杂度是对数级的. code B 易知\(p\in[l,r]\),且最终的利润关于\(p\)的表达式为\(\frac{( ...
- Comet OJ - Contest #2简要题解
Comet OJ - Contest #2简要题解 前言: 我没有小裙子,我太菜了. A 因自过去而至的残响起舞 https://www.cometoj.com/contest/37/problem/ ...
- Comet OJ - Contest #5 简要题解
好久没更博了,还是象征性地更一次. 依然延续了简要题解的风格. 题目链接 https://cometoj.com/contest/46 题解 A. 迫真字符串 记 \(s_i\) 表示数字 \(i\) ...
- Comet OJ Contest #13 简要题解
C2 首先用并查集维护\(1\)的连通块,然后用另外一个并查集维护第\(i\)行中,第\(j\)列之后的第一个\(0\)的位置,就是如果当前位置是\(1\)那么它的父亲是它右边的格子,否则是它自己. ...
- 【题解】NOIP2017 提高组 简要题解
[题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...
- 【题解】NOIP2016 提高组 简要题解
[题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...
- [Codeforces Round #431]简要题解
来自FallDream的博客,未经允许, 请勿转载,谢谢. 好久没写cf题解了zzz 代码比较丑不贴了,cf上都可以看 Div2A. 给你一个长度为n(n<=100)的序列 判断是否可以分成奇数 ...
- Codeforces Round#433 简要题解
来自FallDream的博客,未经允许,请勿转载,谢谢. 我的号自从几个月前姿势水平过低疯狂掉分之后就没动过了 突然想上点分 就打了一场Div1 没想到打到了rank5 一发上橙了,可还行. ...
- Codeforces Round#432 简要题解
来自FallDream的博客,未经允许,请勿转载,谢谢. Div2A 小判断题 Div2B 小判断题,合法的条件是|AB|=|BC|且三点不共线 Div1A 类比二维.三维空间,可以猜测n太大的时候没 ...
随机推荐
- Python基础:00概述
1:续行符 在Python中,一般是一行一个语句.一个过长的语句可以使用反斜杠( \ )分解成几行. 有两种例外情况,一个语句不使用反斜线也可以跨行.在使用闭合操作符时,单一语句可以跨多行,例如:在含 ...
- python----操作Memcache、redis、RabbitMQ、SQLAlchemy
操作本质都是通过socket发送命令 Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次 ...
- oracle trunc(d1[,c1])
[功能]:返回日期d1所在期间(参数c1)的第一天日期 [参数]:d1日期型,c1为字符型(参数),c1默认为j(即当前日期) [参数表]:c1对应的参数表: 最近0点日期: 取消参数c1或j 最近的 ...
- USDT钱包安装
安装USDT钱包 wget https://bintray.com/artifact/download/omni/OmniBinaries/omnicore-0.4.0-x86_64-linux-gn ...
- CondaHTTPError: HTTP 000 CONNECTION FAILED
[root@localhost ~]# conda install samtools Solving environment: failed CondaHTTPError: HTTP 000 CONN ...
- Python学习--not语句
布尔型True和False,not True为False,not False为True,以下是几个常用的not的用法: (1) not与逻辑判断句if连用,代表not后面的表达式为False的时候,执 ...
- 深入Java线程管理(五):线程池
这几天主要是狂看源程序,在弥补了一些以前知识空白的同时,也学会了不少新的知识(比如 NIO),或者称为新技术吧. 线程池就是其中之一,一提到线程,我们会想到以前<操作系统>的生产者与消费者 ...
- Java RandomAccessFile用法(转载)
RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须 ...
- C#的循环语句(一)
循环:反复执行某段代码. 循环四要素:初始条件,循环条件,循环体,状态改变.for(初始条件;循环条件;状态改变) {循环体} for 格式: for(int i=1/*初始条件*/;0<=10 ...
- 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树
题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...