codeforces Hello 2019
codeforces Hello 2019
Hello candidate master
然而没有紫,D题空间少开了1e6,fst了呜呜呜
新年第一场cf2333
感觉难度比 good bye 2018良心很多啊
T1
日常送分题,判断有没有相同的
#include<map>
#include<queue>
#include<cmath>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
char s[10],t[10];
int main(){
// freopen("1.in","r",stdin);
scanf("%s",s+1);
for(int i=1;i<=5;i++){
scanf("%s",t+1);
if(s[1]==t[1]||s[2]==t[2]){
printf("YES\n");
return 0;
}
}
printf("NO\n");
return 0;
}
T2
日常送分题 x 2
#include<map>
#include<queue>
#include<cmath>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=20;
int n,a[maxn];
void dfs(int x,int y){
if(x>n){
if(y%360==0){
printf("YES\n");
exit(0);
}
return;
}
dfs(x+1,y+a[x]);
dfs(x+1,y-a[x]);
}
int main(){
// freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
dfs(1,0);
printf("NO");
return 0;
}
T3
。。。我去怎么三道sb题
对于每个括号序列,统计它左边和右边分别需要补几个,如果都要补就没法用,否则设补左边正,补右边负,开个\(map\)存一下取最小值就好了
#include<map>
#include<queue>
#include<cmath>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=5e5+100;
int n,b[maxn],num;
char s[maxn];
map<int,int>p;
map<int,bool>cz;
int main(){
// freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
int len=strlen(s+1),l=0,r=0;
for(int j=1;j<=len;j++)
if(s[j]=='(') l++;
else
if(l) l--;
else r++;
if(l&&r) continue;
int k;
if(l) k=l;
else k=-r;
p[k]++;
if(k<0&&!cz[k]) cz[k]=1,b[++num]=k;
}
int ans=0;
for(int i=1;i<=num;i++)
ans+=min(p[b[i]],p[-b[i]]);
ans+=p[0]/2;
printf("%d\n",ans);
return 0;
}
T4
题意:一个数n,每次将自己等概率变为自己的一个约数,问变了K次后的n期望大小 (n<1e14 , k<1e4)
把n分解质因数,设\(n=p_1^{k_1}p_2^{k_2}...p_m^{k_m}\)
可以发现,每变一次,每个指数\(k_i\)都会等概率地变成\(0-k_i\)中的一个
那么我们对于每个质因数都求一下他的期望,然后全都乘起来应该就是最后的答案了
对于一个质因数\(p_i^{k_i}\),怎么算他的期望呢?
设\(k_i\)变了\(j\)次变成\(x\)的概率为\(f[j][x]\),因为\(x\)一定是由一个大于等于\(x\)的数\(y\)以\(1/(y+1)\)(有可能变成零,所以是\(y+1\))的概率变来的,所以
\[f[j][x]=\sum_{y=x}^{k_i}{f[j-1][y]*inv[y+1]}
\]
当然,\(f[0][k_i]=1\)
\(f[n][i]\)都求出来了,那么这个质因数的期望就是\(\sum_{i=1}^{k_i}{f[n][i]*pow(p,i)}\)
然后这个\(dp\)可以用前缀和优化(\(y\)按照从\(k_i\)到\(x\)来枚举)时间复杂度\(O(K*k_i)\)
\(n\)的质因数个数以及每个质因数的次数\(k_i\)都是\(logn\)级别的
所以总时间复杂度\(O(Klog ^2n)\)
#include<map>
#include<queue>
#include<cmath>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=3e7;
const ll P=1e9+7;
int p[maxn],num;
ll n,k,inv[10000],f[2][10000],b[10000],tot,c[10000];
bool vis[maxn];
void ycl(){
int lim=3e7;
for(int i=2;i<lim;i++){
if(!vis[i])
p[++num]=i;
for(int j=1;1ll*p[j]*i<lim;j++){
vis[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
inv[0]=inv[1]=1;
for(int i=2;i<=1000;i++)
inv[i]=(1ll*(P-P/i)*inv[P%i])%P;
}
inline ll poww(ll x,ll y){
ll base=1;
while(y){
if(y&1) base=base*x%P;
x=x*x%P;
y>>=1;
}
return base;
}
ll work(ll x,int y){
for(int i=0;i<=y;i++) f[0][i]=0;
int nw=0;f[0][y]=1;
for(int i=1;i<=k;i++){
nw^=1;
ll siz=0;
for(int j=y;j>=0;j--){
siz+=f[nw^1][j]*inv[j+1]%P,siz%=P;
f[nw][j]=siz;
}
}
ll siz=0;
for(int i=0;i<=y;i++)
siz+=poww(x,i)*f[nw][i]%P,siz%=P;
siz%=P;
return siz;
}
int main(){
// freopen("1.in","r",stdin);
//freopen(".out","w",stdout);
ycl();
scanf("%I64d%I64d",&n,&k);
for(int i=1;i<=num&&p[i]<=n;i++)
if(n%p[i]==0){
b[++tot]=p[i];
while(n%p[i]==0) n/=p[i],c[tot]++;
}
ll ans=1;
for(int i=1;i<=tot;i++)
ans=ans*work(b[i],c[i])%P;
if(n!=1) ans=ans*work(n,1)%P;
printf("%I64d\n",(ans%P+P)%P);
return 0;
}