Problem 1st : https://www.lydsy.com/JudgeOnline/problem.php?id=2160
BZOJ2160 拉拉队训练(国家集训队作业) : manacher + ksm计数
code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 19930726; const int maxn = 1e6 + 3; char Ma[maxn<<1]; int Mp[maxn<<1]; ll cnt[maxn]; vector<ll> v; void Manacher(char s[],int len) { int l=0; Ma[l++]='$'; Ma[l++]='#'; for(int i=0;i<len;i++) { Ma[l++]=s[i]; Ma[l++]='#'; } int mx=0,id=0; for(int i=0;i<l;i++) { Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1; while(Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++; if(i+Mp[i]>mx) id=i,mx=i+Mp[i]; } } ll ksm(ll a,ll b) { ll ans=1; while(b) { if(b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } int main() { int n; ll k,ans=1,now=0; char s[maxn]; scanf("%d%lld%s",&n,&k,s); int len=strlen(s); Manacher(s,len); for(int i=2;i<2*len+2;i+=2) cnt[Mp[i]-1]++; for(int i=n;i>=1;i--) if(i%2) { now+=cnt[i]; if(k>=now) { ans=ans*ksm((ll)i,now)%mod; k-=now; } else { ans=ans*ksm((ll)i,k)%mod; k-=now; break; } } if(k>0) ans=-1; printf("%lld",ans); return 0; }Problem 2nd : https://www.lydsy.com/JudgeOnline/problem.php?id=3942
BZOJ3942 Censoring(USACO Silver) : 不断从A字符串中删除B字符串,直到无法继续删除,kmp + 栈
code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6 + 3; int Next[maxn],now,tot,f[maxn]; char ans[maxn]; void get_next(char x[],int len) { Next[1]=0; for(int i=2,j=0;i<=len;i++) { while(j>0&&x[i]!=x[j+1]) j=Next[j]; if(x[i]==x[j+1]) j++; Next[i]=j; } } int main() { char s[maxn],t[maxn]; scanf("%s%s",s+1,t+1); int n=strlen(s+1),m=strlen(t+1); get_next(t,m); for(int i=1,j=0;i<=n;i++) { ans[tot++]=s[i]; while(j>0&&(j==n||ans[tot-1]!=t[j+1])) j=Next[j]; if(ans[tot-1]==t[j+1]) j++; f[tot-1]=j; if(j==m) { tot-=m; j=f[tot-1]; } } for(int i=0;i<tot;i++) printf("%c",ans[i]); return 0; }
Problem 3rd : https://www.lydsy.com/JudgeOnline/problem.php?id=3940
BZOJ3940 Censoring(USACO Gold) : Problem 2nd的进阶版,B字符串变成多个不同的模式串,AC自动机 + 栈
code :
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 4; struct Trie { int fail,ch[27],len; }ac[maxn]; int tot,pos[maxn],top; char ans[maxn]; void Insert(char s[]) { int len=strlen(s),now=0; for(int i=0;i<len;i++) { if(!ac[now].ch[s[i]-'a']) ac[now].ch[s[i]-'a']=++tot; now=ac[now].ch[s[i]-'a']; } ac[now].len=max(ac[now].len,len); } void build() { ac[0].fail=0; queue<int> q; for(int i=0;i<26;i++) if(ac[0].ch[i]) { ac[ac[0].ch[i]].fail=0; q.push(ac[0].ch[i]); } while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<26;i++) if(ac[now].ch[i]) { ac[ac[now].ch[i]].fail=ac[ac[now].fail].ch[i]; q.push(ac[now].ch[i]); } else ac[now].ch[i]=ac[ac[now].fail].ch[i]; } } void query(char s[]) { int now=0,len=strlen(s),tmp; for(int i=0;i<len;i++) { now=ac[now].ch[s[i]-'a']; ans[++top]=s[i]; pos[top]=now; if(ac[now].len) { top-=ac[now].len; now=pos[top]; } } } int main() { char s[maxn],t[maxn]; int n; scanf("%s%d",s,&n); for(int i=0;i<=maxn;i++) ac[i].len=0; for(int i=1;i<=n;i++) { scanf("%s",t); Insert(t); } build(); query(s); for(int i=1;i<=top;i++) printf("%c",ans[i]); printf("\n"); return 0; }
Problem 4th : https://www.lydsy.com/JudgeOnline/problem.php?id=2434