String Mark Codeforces - 895D
一看好像会做的样子,就去做了一下,结果
猝不及防地T掉了
赶紧查了一下,没有死循环,复杂度也是对的,无果,于是翻了题解
题解没看懂,但是找到了标程,然后发现我被卡常了。。。
而且好像当时还过了前10个点啊。。这要真的是比赛稳稳的FST啊
小技巧:
逆元只需要求inv[i]和inv[i!],可以预处理出来
令md=1e9+7
则inv[1]=1
除此外inv[i]=(md-md/i)*inv[md%i]%md
令inv2[i]=inv[i!]
则inv2[n]=pow(n!,md-2)
除此外inv2[i]=inv2[i+1]*(i+1)%mod;
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define md 1000000007
using namespace std;
typedef long long LL;
LL poww(LL a,LL b)
{
LL base=a,ans=;
while(b)
{
if(b&) ans=(ans*base)%md;
b>>=;
base=(base*base)%md;
}
return ans;
}
LL inv[],inv2[],jc[],sum,sumx,num[],ans,n;
char s1[],s2[];
void addx(LL x)
//num[x]++,同时维护sum,sumx
{
sum=sum*jc[num[x]]%md;
num[x]++;sumx++;
sum=sum*sumx%md;
sum=sum*inv2[num[x]]%md;
}
void delx(LL x)
{
sum=sum*jc[num[x]]%md;
sum=sum*inv[sumx]%md;#include
#include
#include
#include
#define md 1000000007
using namespace std;
typedef long long LL;
LL poww(LL a,LL b)
{
LL base=a,ans=1;
while(b)
{
if(b&1) ans=(ans*base)%md;
b>>=1;
base=(base*base)%md;
}
return ans;
}
LL inv[1000100],inv2[1000100],jc[1000100],sum,sumx,num[30],ans,n;
char s1[1000100],s2[1000100];
void addx(LL x)
//num[x]++,同时维护sum,sumx
{
sum=sum*jc[num[x]]%md;
num[x]++;sumx++;
sum=sum*sumx%md;
sum=sum*inv2[num[x]]%md;
}
void delx(LL x)
{
sum=sum*jc[num[x]]%md;
sum=sum*inv[sumx]%md;
sumx--;num[x]--;
sum=sum*inv2[num[x]]%md;
}
//s1的所有排列中小于s2的个数-s1的所有排列中小于s1的个数+1
int main()
{
LL i,j;
scanf("%s",s1+1);
scanf("%s",s2+1);n=strlen(s2+1);
jc[0]=1;
for(i=1;i<=1000000;i++) jc[i]=jc[i-1]*i%md;
inv[1]=1;
for(i=2;i<=1000000;i++) inv[i]=(md-md/i)*inv[md%i]%md;
for(i=0;i<=1000000;i++) inv2[i]=poww(jc[i],md-2);
for(i=1;i<=n;i++) num[s1[i]-'a']++;
sum=jc[n];sumx=n;
for(i=0;i<26;i++) sum=sum*inv2[num[i]]%md;
for(i=1;i<=n;i++)
{
for(j=0;j<s2[i]-'a';j++)
if(num[j])
{
delx(j);
ans=(ans+sum)%md;
addx(j);
}
if(num[s2[i]-'a']) delx(s2[i]-'a');
else break;
}
for(i=0;i<26;i++) num[i]=0;
for(i=1;i<=n;i++) num[s1[i]-'a']++;
sum=jc[n];sumx=n;
for(i=0;i<26;i++) sum=sum*inv2[num[i]]%md;
for(i=1;i<=n;i++)
{
for(j=0;j<s1[i]-'a';j++)
if(num[j])
{
delx(j);
ans=(ans-sum+md)%md;
addx(j);
}
if(num[s1[i]-'a']) delx(s1[i]-'a');
else break;
}
ans=(ans-1+md)%md;
printf("%lld",ans);
return 0;
} sumx--;num[x]--;
sum=sum*inv2[num[x]]%md;
}
//s1的所有排列中小于s2的个数-s1的所有排列中小于s1的个数+1
int main()
{
LL i,j;
scanf("%s",s1+);
scanf("%s",s2+);n=strlen(s2+);
jc[]=;
for(i=;i<=;i++) jc[i]=jc[i-]*i%md;
inv[]=;
for(i=;i<=;i++) inv[i]=(md-md/i)*inv[md%i]%md;
for(i=;i<=;i++) inv2[i]=poww(jc[i],md-);
for(i=;i<=n;i++) num[s1[i]-'a']++;
sum=jc[n];sumx=n;
for(i=;i<;i++) sum=sum*inv2[num[i]]%md;
for(i=;i<=n;i++)
{
for(j=;j<s2[i]-'a';j++)
if(num[j])
{
delx(j);
ans=(ans+sum)%md;
addx(j);
}
if(num[s2[i]-'a']) delx(s2[i]-'a');
else break;
}
for(i=;i<;i++) num[i]=;
for(i=;i<=n;i++) num[s1[i]-'a']++;
sum=jc[n];sumx=n;
for(i=;i<;i++) sum=sum*inv2[num[i]]%md;
for(i=;i<=n;i++)
{
for(j=;j<s1[i]-'a';j++)
if(num[j])
{
delx(j);
ans=(ans-sum+md)%md;
addx(j);
}
if(num[s1[i]-'a']) delx(s1[i]-'a');
else break;
}
ans=(ans-+md)%md;
printf("%lld",ans);
return ;
}
原来的代码(假的)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define md 1000000007
using namespace std;
typedef long long LL;
LL poww(LL a,LL b)
{
LL base=a,ans=;
while(b)
{
if(b&) ans=(ans*base)%md;
b>>=;
base=(base*base)%md;
}
return ans;
}
LL inv[],inv2[],jc[],sum,sumx,num[],ans,n;
char s1[],s2[];
void addx(LL x)
//num[x]++,同时维护sum,sumx
{
sum=sum*jc[num[x]]%md;
num[x]++;sumx++;
sum=sum*sumx%md;
sum=sum*inv2[num[x]]%md;
}
void delx(LL x)
{
sum=sum*jc[num[x]]%md;
sum=sum*inv[sumx]%md;
sumx--;num[x]--;
sum=sum*inv2[num[x]]%md;
}
//s1的所有排列中小于s2的个数-s1的所有排列中小于s1的个数+1
int main()
{
LL i,j;
scanf("%s",s1+);
scanf("%s",s2+);n=strlen(s2+);
jc[]=;
for(i=;i<=;i++) jc[i]=jc[i-]*i%md;
inv[]=;
for(i=;i<=;i++) inv[i]=(md-md/i)*inv[md%i]%md;
for(i=;i<=;i++) inv2[i]=poww(jc[i],md-);
for(i=;i<=n;i++) num[s1[i]-'a']++;
sum=jc[n];sumx=n;
for(i=;i<;i++) sum=sum*inv2[num[i]]%md;
for(i=;i<=n;i++)
{
for(j=;j<s2[i]-'a';j++)
if(num[j])
{
delx(j);
ans=(ans+sum)%md;
addx(j);
}
if(num[s2[i]-'a']) delx(s2[i]-'a');
else break;
}
for(i=;i<;i++) num[i]=;
for(i=;i<=n;i++) num[s1[i]-'a']++;
sum=jc[n];sumx=n;
for(i=;i<;i++) sum=sum*inv2[num[i]]%md;
for(i=;i<=n;i++)
{
for(j=;j<s1[i]-'a';j++)
if(num[j])
{
delx(j);
ans=(ans-sum+md)%md;
addx(j);
}
if(num[s1[i]-'a']) delx(s1[i]-'a');
else break;
}
ans=(ans-+md)%md;
printf("%lld",ans);
return ;
}
String Mark Codeforces - 895D的更多相关文章
- Codeforces 895.D String Mark
D. String Mark time limit per test 4 seconds memory limit per test 256 megabytes input standard inpu ...
- String Typing CodeForces - 954B
题意: 给一个字符串,可以复制某一段字符,问最少需要多少步能将其输出,比如abcabcd,先输入abc然后再赋值abc再输入d就只需要5步. 复制的这段字符 必须是从字符串的0位置开始复制的 而且只 ...
- Vasya and Binary String(来自codeforces
题目大意: 给定一个0/1字符串,每次你可以将此字符串中一段连续的任意长度的0/1子串消除掉,注意每次消除的子串中只能有0或者1一种字符,消除掉一串长度为i的0/1字符串会得到a[i]的收益,问将这个 ...
- Playing with String(codeforces 305E)
题意:刚开始你只有一个字符串每次能选择一个有的字符串 s,找到 i,满足s[i - 1] = s[i + 1],将其分裂成 3 个字符串s[1 · · · i - 1]; s[i]; s[i + 1 ...
- Codeforces #402
目录 Codeforces #402 Codeforces #402 Codeforces 779A Pupils Redistribution 链接:http://codeforces.com/co ...
- Codeforces Round #300 A. Cutting Banner 水题
A. Cutting Banner Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/538/pro ...
- Codeforces Round #448
Pizza Serparation #include<stdio.h> #include<string.h> #include<stdlib.h> #include ...
- CodeForces - 999B Reversing Encryption
B - Reversing Encryption A string s of length n can be encrypted by the following algorithm: iterate ...
- c++ hex string array 转换 串口常用
c++ hex string array 转换 效果如下 tset string is follow 0x50 55 0x35 00 10 203040506073031323334ff format ...
随机推荐
- Jmeter的几个关键配置文件
1.配置文件位于bin目录下: 2.配置文件可能存在优先级关系,好像user.properties会覆盖jmeter.properties,一般修改配置都是修改或者添加user.properties, ...
- 【c++】C++中const用法总结
1. const常量,如const int max = 100; 优点:const常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全 ...
- CentOS5 忘记root密码的解决办法
方法/步骤 1 开机启动的时候,按“E”进入如下界面. 2 选择相应的内核,再次按“E”,出现下图,选择第二项,再次按“E”键 3 在尾部加:“空格+single”(如图),Enter.图如下: ...
- Visual Studio VS2010 如何修改默认的编辑语言
1 比如我要把默认是C++的配置改成C#,在工具-导入和导出设置中,重置所有设置 2 这里改成新的语言 3 重置完成
- Rust 1.7.0 语法基础 sep_token 和 non_special_token
一.分隔符 sep_token 指的是分隔符, 是除了 * 和 + 之外的不论什么符号,通常情况下是使用 , 逗号. 比如: 宏的多个參数分隔,以下代码中的逗号就是 sep_token (target ...
- web编程非常实用的在线工具大全
目前,不管是前端开发人员还是个人站长,经常需要一些代码处理类的工具,比如:代码对比.代码格式化.图标制作等.有时就是一时急用可电脑上又没有安装相关的软件,这里为大家收集了一些我们经常会用到的在线工具. ...
- 邮件:事务失败。 服务器响应为:DT:SPM 163 smtp
几年前我做的一个项目,日发邮件最高峰时几十万.自以为对邮件发送方面已经有了一定认识,所以近期机缘巧合之下,又有项目需要发送邮件,不禁自信满满,暗自庆幸能不手到擒来乎? 不想老革命遇到新问题.我原先的邮 ...
- 2016/05/23 thinkphp M方法和D方法的区别
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...
- 安装mint的问题集锦
1.修改DNS解析配置 刚刚安装完mint可能现无法连接源的问题,总是说dns解析错误,这个可能是dns配置文件造成的,因为官网下的mint很可能是配置了国外的dns解析,比如我刚安上时,就是默认配置 ...
- Datatables 1.10.x在命名上与1.9.x
1.10.x与1.9.x参数名对照表 Datatables 1.10.x在命名上与1.9.x的有区别,新版的使用的是驼峰的命名规则,而之前的是采用匈牙利命名规则 当然,这些变化都是向下兼容的,你可以继 ...