【题解】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太大的时候没 ...
随机推荐
- mysql把一个表的字段update成另一个表的字段根据id
mysql把一个表的字段update成另一个表的字段根据id 1.填充activity表里面的creator字段,用org的founderid,其中activity的orgid要和org的id对应,具 ...
- idea使用积累
1.初试化配置参照http://m.blog.csdn.net/robertohuang/article/details/75042116,很详细. 2.idea中忽略.idea,.iml这两个文件 ...
- UITableView 刷新问题
遇到的问题: 在程序里异步请求服务器后回调函数中处理数据和界面数据的刷新,但是更新UITableView的时候总是很慢才更新完,打印TableView的代理方法也都很快打印. 解决办法就是: [sel ...
- Java 内存模型及GC原理 (转)
来源:http://blog.csdn.net/ithomer/article/details/6252552 一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性 ...
- @bzoj - 4379@ [POI2015] Modernizacja autostrady
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一棵无根树,边权都是1,请去掉一条边并加上一条新边,定义直径 ...
- 2011-04-21 运程连Oracle的方法
oracle无法远程连接重要原因,即使防火墙开放1521端口, 但是返回包可能是随机端口,所以仍有可能被防火墙阻止. 解决方法: 在注册表中增加一个字符串值如下.可解决 花费两天找到的方法 [HKEY ...
- codeforces1253F(图转换为树减少复杂度)
题意: 给定一个无向图,其中1-k为充电桩,然后给定q个询问\(u_i, v_i\)(都是充电桩),然后问从其中一个充电桩到达另外一个充电桩需要最小的电池的容量. 每经过一条边都需要消耗一定的能量,到 ...
- 【CSS3】纯CSS3制作页面切换效果
此前写的那个太复杂了,来点简单的核心 <html> <head> <title></title> <style type="text/c ...
- 用户注册页的布局及js逻辑实现(正则,注册按钮)
文章地址:https://www.cnblogs.com/sandraryan/ 先写一个简单的静态页面,然后对用户输入的内容进行验证,判断输入的值是否符合规则,符合规则进行注册 先上静态页面 < ...
- Java 简单校验框架
数据校验框架现状 在我们的方法入口后面,难免会有如下样子的代码: result.setSuccess(false); if (StringUtils.isBlank(bizOrder.getThird ...