[USACO22DEC] Palindromes P 题解
T3 [USACO22DEC] Palindromes P
郝题。首先考虑给定一个串
易得,不可能交换两个本来就相同的字符。不妨观察
简单手模应该不难得到。要注意特殊情况:
- 若串长为偶数但
的个数为奇数,不可能为回文串, 走人; - 否则一定存在一个
在正中间的位置,计算 。
所以我们就有一个
一般来说想到这里就差不多了。
我们发现可以转变转移方式,由中间向两边扩展。先枚举
感觉重点还是在于发现这个式子。
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
using namespace std;
using ll=long long;
constexpr int MAXN=7505;
int t[MAXN],n;
string s;
struct BIT{
ll c[MAXN<<1];
void add(int x,int k){
while(x<=n<<1)c[x]+=k,x+=lowbit(x);
}
ll sum(int x){
ll res=0;
while(x)res+=c[x],x-=lowbit(x);
return res;
}
void clear(){
memset(c,0,sizeof(c));
}
}t1,t2;
int main(){
ios::sync_with_stdio(0);
cin.tie(nullptr),cout.tie(nullptr);
cin>>s;
n=s.size();
s=' '+s;
int c=0;
for(int i=1;i<=n;++i)if(s[i]=='G')t[++c]=i;
t[c+1]=n+1;
ll ans=0,sum=0,lans=0;
for(int i=1;i<=c;++i){
int lf=i,rf=i;
while(lf&&rf<=c){
int fk=t[lf]+t[rf];
if(lf^i){
t1.add(fk,fk),t2.add(fk,1);
sum+=fk;
++lans;
}
for(int l=t[lf];l>t[lf-1];--l)
for(int r=t[rf];r<t[rf+1];++r){
if((r-l+1)%2==0){
--ans;
continue;
}
ll p=t2.sum(l+r-1),q=t1.sum(l+r-1);
ans+=abs((l+r)/2-t[i]);
ans+=(p*(l+r)-q)+(sum-q)-(lans-p)*(l+r);
}
--lf,++rf;
}
sum=lans=0;
t1.clear(),t2.clear();
}
for(int i=1;i<c;++i){
int lf=i,rf=i+1;
while(lf&&rf<=c){
int fk=t[lf]+t[rf];
t1.add(fk,fk),t2.add(fk,1);
sum+=fk;
++lans;
for(int l=t[lf];l>t[lf-1];--l)
for(int r=t[rf];r<t[rf+1];++r){
ll p=t2.sum(l+r-1),q=t1.sum(l+r-1);
ans+=(p*(l+r)-q+(sum-q)-(lans-p)*(l+r));
}
--lf,++rf;
}
sum=lans=0;
t1.clear(),t2.clear();
}
cout<<ans<<'\n';
return 0;
}
即得易见平凡,仿照上例显然。留作习题答案略,读者自证不难。
反之亦然同理,推论自然成立。略去过程 ,由上可知证毕。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现