字符串杂选
考虑
发现答案即
#include <bits/stdc++.h>
#define ll long long
using std::cin; using std::cout; using std::cerr;
const int N=1e6+10;
int nxt[N];
char a[N];
int n;
inline void getnxt(void){
int j=0;
for(int i=2;i<=n;++i){
while(j&&a[i]!=a[j+1]) j=nxt[j];
if(a[i]==a[j+1]) ++j;
nxt[i]=j;
}
}
int main(){
cin>>n;
cin>>a+1;
getnxt();
cout<<n-nxt[n];
return 0;
}
考虑到这道题又要求拼接,而且又出现前缀。所以继续考虑
但是这题还要求长度最大周期,也就是剩下的一段最小,所以可以考虑直接求一个
但是有些时候是不会被计算的,因为这个串并不会存在一个周期,这个时候这个串肯定会
因为数据范围高达
#include <bits/stdc++.h>
#define ll long long
#define int long long
using std::cin; using std::cout; using std::cerr;
const int N=1e6+10;
int nxt[N],fail[N];
char a[N];
int n,ans;
inline void getnxt(void){
int j=0;
for(int i=2;i<=n;++i){
while(j&&a[j+1]!=a[i]) j=fail[j];
if(a[i]==a[j+1]) ++j;
fail[i]=j;
}
j=0;
for(int i=2;i<=n;++i){
j=fail[i];
nxt[i]=(nxt[j]==0?fail[i]:nxt[j]);
}
}
signed main(){
cin>>n>>a+1;
getnxt();
for(int i=2;i<=n;++i){
if(i-nxt[i]>=ceil(i/2.0) && nxt[i])
ans+=i-nxt[i];
}
return cout<<ans<<"\n",0;
}
彬哥甚至可以想出这个题的思路。虽然他好像不是很会写
题意:添加最少的字符使整个串回文起来。
那直接计算最长的可以接触到整个串末尾位置就好了。也就是
你看这个题目标题也应该知道这题目的做法了吧。 ——周老
#include <bits/stdc++.h>
#define ll long long
#define f(x) (x<<1|1)
using std::cin;
using std::cout;
const int N=2.2e7+10;
int r[N],a[N],b[N];
int center,limit,ans;
int n;
char ch[N];
int main(){
cin>>n;
cin>>(ch+1);
for(int i=1;i<=n;++i)
b[i]=ch[i]+1;
for(int i=1;i<=n;++i)
a[2*i-1]=200,a[2*i]=b[i];
a[n<<1|1]=200;
for(int i=1;i<=(n<<1|1);++i){
if(i<=limit) r[i]=std::min(limit-i,r[2*center-i]);
while(i-r[i]>=1&&a[i-r[i]]==a[i+r[i]]) ++r[i];
if(i+r[i]>limit) center=i,limit=i+r[i];
}
for(int i=(n<<1|1);i>=1;--i){
if(i+r[i]-1==f(n)) ans=f(n)-(f(n)-i)*2-1;
}
cout<<ans/2<<'\n';
}
先用
然后对于每个
先把所以
贪心。如果字典树上面存在
最后去找所有
细节:要添加前导零。
// Qx 's data
#include <bits/stdc++.h>
#define int long long
#define fir first
#define sec second
#define add push_back
using std::cin;
using std::cout;
using std::cerr;
const int N=1e6+10,limit=35;
struct Node{
int num,son[2];
}T[N];
int cnt,n,m;
void Insert(std::vector<int> s){
int now=0;
for(int ch:s){
if(!T[now].son[ch]) T[now].son[ch]=++cnt;
now=T[now].son[ch], T[now].num++;
}
}
std::vector<int> Find(std::vector<int> s){
int now=0;
std::vector<int> res;
for(int ch:s){
if(T[now].son[ch^1]) res.add(1), now=T[now].son[ch^1];
else res.add(0), now=T[now].son[ch];
}
return res;
}
int ans;
int s[N],a[N];
std::vector<std::pair<int,int> > G[N];
void dfs(int u,int f){ for(std::pair<int,int>pr:G[u]) if(pr.fir^f) s[pr.fir]=pr.sec^s[u], dfs(pr.fir,u); }
inline void to2(std::vector<int>& vec,int x){
int num1=x,ret=0;
while(x) vec.push_back(x&1), x>>=1;
while(num1) ret++,num1>>=1;
int p=limit-ret;
while(p--) vec.add(0);
reverse(vec.begin(),vec.end());
}
int to10(std::vector<int> vec){
reverse(vec.begin(),vec.end());
int answer=0,base=1;
for(int x:vec) answer+=x*base,base<<=1;
return answer;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<n;++i){
int opu,opv,opw;
scanf("%lld%lld%lld",&opu,&opv,&opw), G[opu].add({opv,opw}), G[opv].add({opu,opw});
}
dfs(1,0);
for(int i=1;i<=n;++i){
std::vector<int> tmp;
tmp.clear();
to2(tmp,s[i]);
Insert(tmp);
}
for(int i=1;i<=n;++i){
std::vector<int> tmp;
to2(tmp,s[i]), ans=std::max(ans,to10(Find(tmp)));
}
return printf("%lld\n",ans),0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律