pyyzDay11
落课了
模拟赛
T1
大炮
dp[i][j]表示第一个串1i和第二个串1j的位置能否匹配
扫一遍判断即可
注意前缀*的情况特判,以及初始化
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bits/stdc++.h>
#define int long long
#define jiaa(a,b) {a+=b;if(a>=MOD) a-=MOD;}
#define jian(a,b) {a-=b;if(a<0) a+=MOD;}
using namespace std;
int ksm(int a,int b,int p){
if(b==0) return 1;
if(b==1) return a%p;
int c=ksm(a,b/2,p);
c=c*c%p;
if(b%2==1) c=c*a%p;
return c%p;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
map<char,bool> mm;
int dp[5005][5005],maxx[5005];
signed main()
{
//freopen("filename.in", "r", stdin);
//freopen("filename.out", "w", stdout);
string S,t;
cin>>S>>t;
string s="";
int N=S.size();
int m=t.size();
for(int i=0;i<m;i++){
mm[t[i]]=1;
}
for(int j=0;j<N;j++){
if(S[j]=='*'||S[j]=='?') continue;
if(!mm[S[j]]){
cout<<"NO"<<'\n';
return 0;
}
}
int fl=0;
for(int i=0;i<N;i++){
if(!fl&&S[i]!='*'){
fl=1;
s+=S[i];
}
else if(fl){
s+=S[i];
}
}
int n=s.size();
if(fl){
for(int j=0;j<m;j++){
if(s[0]==t[j]||s[0]=='?') dp[0][j]++;
}
}
else{
if(s[0]==t[0]||s[0]=='?') dp[0][0]++;
else{
cout<<"NO"<<'\n';
return 0;
}
}
for(int i=1;i<n;i++){
for(int j=0;j<m;j++){
if(s[i]>='a'&&s[i]<='z'){
if(s[i]==t[j]&&dp[i-1][j-1]>0) dp[i][j]++;
}
else if(s[i]=='?'){
if(dp[i-1][j-1]>0) dp[i][j]++;
}
else{
if(dp[i-1][j-1]){
dp[i][j]++;
dp[i+1][j]++;
}
if(maxx[i-1]) dp[i][j]++;
}
maxx[i]=max(maxx[i],dp[i][j]);
}
}
if(dp[n-1][m-1]>0) cout<<"YES"<<'\n';
else cout<<"NO"<<'\n';
return 0;
}
T2
考虑n^2暴力
枚举A|At|A两个断点
hash判断是否相等即可
考虑优化掉枚举断点
对整个字符串进行manacher预处理每个点回文最大长度
现在枚举断点i
发现A At和At A都是回文
即需要找到满足 j<=di+i且 i>=j-dj的所有j点
显然树状数组做即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bits/stdc++.h>
#define int long long
#define jiaa(a,b) {a+=b;if(a>=MOD) a-=MOD;}
#define jian(a,b) {a-=b;if(a<0) a+=MOD;}
using namespace std;
int ksm(int a,int b,int p){
if(b==0) return 1;
if(b==1) return a%p;
int c=ksm(a,b/2,p);
c=c*c%p;
if(b%2==1) c=c*a%p;
return c%p;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
#define lowbit(x) x&(-x)
int d[2000005];
const int MAXN=2000005;
int sum[MAXN];
vector<int> del[2000005];
void modify(int x,int y){
for(int i=x;i<=MAXN;i+=lowbit(i)){
sum[i]+=y;
}
}
int query(int x){
int ans=0;
for(int i=x;i;i-=lowbit(i)){
ans+=sum[i];
}
return ans;
}
signed main()
{
//freopen("filename.in", "r", stdin);
//freopen("filename.out", "w", stdout);
string s;
string T=" *";
cin>>s;
int nn=s.size();
for(int i=0;i<nn;i++){
T+=s[i];
T+='*';
}
int mid=0,r=-1;
int n=T.size();
int ans=0;
for(int i=1;i<n;i++){
if(i<r) d[i]=min(r-i+1,d[2*mid-i]);
int x=i-d[i];
int y=i+d[i];
while(y<n&&x&&T[x]==T[y]){
d[i]++;
y++;
x--;
}
if(d[i]+i-1>r){
r=d[i]+i-1;
mid=i;
}
}
for(int i=1;i<n;i+=2){
for(auto ed:del[i]) modify(ed,-1);
ans-=query(i-d[i]);
ans+=query(i);
modify(i,1);
del[i+d[i]+1].push_back(i);
}
cout<<ans<<'\n';
return 0;
}

浙公网安备 33010602011771号