2021年集训(8.26~8.28)
2021年集训顺利收官,转眼间5周已过,这5周可谓收获满满,如果能在明天的2021CCPC网络选拔赛顺利突围就更好不过了,但是几率可谓相当的小啊,三千多支队伍一起打选拔赛,才决出来几百支队伍,而且其中高手如林,北大的逆十字也来了,这就说明当年的国家队队长周雨扬也来了,一想到此就十分地激动啊。但是不得不说CCPC的网络选拔赛是真的离谱,没任何监控,全靠自觉,作弊的人肯定不少,而且这几年的网选赛后台数据早被喷爆了,还不整改,硬生生地打成OI,就离谱。
统计难题
传送门
//https://vjudge.ppsucxtt.cn/contest/455495#problem/A
#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
using namespace std;
map <string,int> mp;
int main()
{
char s[15];
while(gets(s))
{
int len=strlen(s);
if(!len)
break;
char t[15]={0};
for(int i=0;i<len;i++)
{
t[i]=s[i];
mp[t]++;
}
}
while(gets(s))
printf("%d\n",mp[s]);
return 0;
}
最长公共子串
传送门
//https://vjudge.ppsucxtt.cn/contest/455495#problem/B
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100005
#define P 131
typedef unsigned long long ull;
int len1,len2;
char s1[N],s2[N];
ull power[N],hs1[N],hs2[N],s[N];
int judge(int mid)
{
for(int i=1;i<=len1-mid+1;i++)
s[i]=hs1[i-1+mid]-hs1[i-1]*power[mid];
int len=len1-mid+1;
sort(s+1,s+1+len);
for(int i=1;i<=len2-mid+1;i++)
{
int pos=lower_bound(s+1,s+1+len,hs2[i-1+mid]-hs2[i-1]*power[mid])-s;
if(s[pos]==hs2[i-1+mid]-hs2[i-1]*power[mid])
return 1;
}
return 0;
}
int main()
{
power[0]=1;
for(int i=1;i<N;i++)
power[i]=power[i-1]*P;
scanf("%s",s1+1);
scanf("%s",s2+1);
len1=strlen(s1+1);
len2=strlen(s2+1);
for(int i=1;i<=len1;i++)
hs1[i]=hs1[i-1]*P+s1[i]-'a'+1;
for(int i=1;i<=len2;i++)
hs2[i]=hs2[i-1]*P+s2[i]-'a'+1;
int l=1,r=min(len1,len2),ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(judge(mid))
ans=mid,l=mid+1;
else
ans=ans,r=mid-1;
}
printf("%d\n",ans);
return 0;
}
最长回文
传送门
//https://vjudge.ppsucxtt.cn/contest/455495#problem/C
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 110005
char s[N],t[2*N];
int Len[2*N];
int init(int len)
{
t[0]='[';
for(int i=1;i<=2*len-1;i+=2)
{
t[i]='$';
t[i+1]=s[i/2];
}
t[2*len+1]='$';
t[2*len+2]=']';
t[2*len+3]=0;
return 2*len+1;
}
int manacher(int len)
{
int pos=0,mx=0,ans=0;
for(int i=1;i<=len;i++)
{
//定位
if(i<mx)
Len[i]=min(Len[2*pos-i],mx-i);
else
Len[i]=1;
//拓展
while(t[i-Len[i]]==t[i+Len[i]])
Len[i]++;
//更新
if(i+Len[i]>mx)
{
pos=i;
mx=i+Len[i];
}
ans=max(ans,Len[i]);
}
return ans-1;
}
int main()
{
while(scanf("%s",&s)!=EOF)
{
int slen=strlen(s);
int tlen=init(slen);
printf("%d\n",manacher(tlen));
}
return 0;
}
Power Strings
传送门
//https://vjudge.ppsucxtt.cn/contest/455495#problem/F
#include <stdio.h>
#include <string.h>
#define N 1000005
char s[N];
int nx[N];
void getnext(int len)
{
int j=-1;
nx[0]=-1;
for(int i=1;i<len;i++)
{
while(s[j+1]!=s[i]&&j>-1)//不同则回溯
j=nx[j];
if(s[j+1]==s[i])//相同则向后
j++;
nx[i]=j;
}
}
int main()
{
while(scanf("%s",&s)!=EOF)
{
if(strcmp(s,".")==0)
break;
memset(nx,0,sizeof(nx));
int len=strlen(s);
getnext(len);
int n=len-nx[len-1]-1;
if(len%n==0)
printf("%d\n",len/n);
else
printf("1\n");
}
return 0;
}
A Secret
传送门
//https://vjudge.ppsucxtt.cn/contest/455495#problem/G
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000005
#define MOD 1000000007
char s1[N],s2[N];
int nx[N];
long long ans[N];
void getnext(int len)
{
nx[0]=nx[1]=0;
for(int i=1;i<len;i++)
{
int j=nx[i];
while(s2[j]!=s2[i]&&j)
j=nx[j];
if(s2[j]==s2[i])
nx[i+1]=j+1;
else
nx[i+1]=0;
}
}
void kmp(int len1,int len2)
{
int j=0;
for(int i=0;i<len1;i++)
{
while(s2[j]!=s1[i]&&j)
j=nx[j];
if(s2[j]==s1[i])
j++;
ans[j]++;
if(j==len2)
{
j=nx[j];
if(j>len2)
j=0;
}
}
}
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
memset(nx,0,sizeof(nx));
memset(ans,0,sizeof(ans));
scanf("%s",&s1);
scanf("%s",&s2);
int len1=strlen(s1);
int len2=strlen(s2);
reverse(s1,s1+len1);
reverse(s2,s2+len2);
getnext(len2);
kmp(len1,len2);
for(int i=len2;i>=1;i--)
ans[nx[i]]+=ans[i];
long long sum=0;
for(int i=1;i<=len2;i++)
sum=(sum+ans[i]*i)%MOD;
printf("%lld\n",sum);
}
return 0;
}