社区讨论
求卡常 悬一关
P7114[NOIP2020] 字符串匹配参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhz4g8li
- 此快照首次捕获于
- 2025/11/15 01:18 3 个月前
- 此快照最后确认于
- 2025/11/16 13:57 3 个月前
CPP
#include<bits/stdc++.h>
#define N 1200005
#define base 11451
#define lowbit(x) x&(-x)
#define int unsigned long long
using namespace std;
char a[N];
int ha[N];
int bk[N];
int tree[N];
string s;
void read()
{
s="";
char ch=getchar();
while(ch<'a'||ch>'z') ch=getchar();
while(ch>='a'&&ch<='z')
{
s+=ch;
ch=getchar();
}
return;
}
void add(int u,int v){
while(u<=N){
tree[u]+=v;
u+=lowbit(u);
}
return;
}
int qu(int u){
int sum=0;
while(u){
sum+=tree[u];
u-=lowbit(u);
}
return sum;
}
int suan(int l,int r){
return ha[r]-ha[l-1]*bk[r-l+1];
}
int cnt[30];
int match[N];
vector<int> vec[N];
vector<int> v1[N];
void write(int x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
signed main(){
//freopen("P7114_23.in","r",stdin);
//freopen("string.out","w",stdout);
bk[0]=1;
for(int i=1;i<N;i++){
bk[i]=bk[i-1]*base;
}
int t;
scanf("%d",&t);
while(t--){
//ch=0;
read();
int l=s.length();
ha[0]=0;
ha[l+1]=0;
for(int i=1;i<=l;i++){
//ch++;
ha[i]=ha[i-1]*base;
ha[i]+=s[i-1]-'a'+1;
}
int cntj=0;
for(int i=1;i<=27;i++){
//ch++;
cnt[i]=0;
}
for(int i=l;i>=1;i--){
//ch++;
cnt[s[i-1]-'a'+1]++;
if(cnt[s[i-1]-'a'+1]%2==1)cntj++;
else cntj--;
match[i-1]=cntj;
}
//cout<<"l:"<<l<<endl;
for(int i=1;i<=l;i++){
int ans1=suan(1,i);
for(int j=1;j+i-1<=l;j+=i){
if(j+i-1==l)continue;
//ch++;
if(suan(j,j+i-1)!=ans1){
break;
}
//cout<<"i:"<<i<<" "<<j<<" "<<match[j+i-1]<<endl;
vec[i].push_back(match[j+i-1]);
}
}
for(int i=1;i<=27;i++){
cnt[i]=0;
}
cntj=0;
for(int i=1;i<=l;i++){
//ch++;
cnt[s[i-1]-'a'+1]++;
if(cnt[s[i-1]-'a'+1]%2==1)cntj++;
else cntj--;
//cout<<"::"<<i+1<<" "<<cntj<<endl;
v1[i+1].push_back(cntj);
}
int ans=0;
int cnt0=0;
int ssum=0;
for(int i=l;i>=1;i--){
for(int j=0;j<vec[i].size();j++){
int k=vec[i][j];
if(k!=0){
ssum++;
add(k,1);
}
else
cnt0++;
}
for(int j=0;j<v1[i].size();j++){
int k=v1[i][j];
if(k!=0){
// cout<<i<<" "<<v1[i][j]<<endl;
// cout<<qu(N)-qu(k-1)<<endl;
ans+=ssum-qu(k-1);
}
else{
// cout<<i<<" "<<v1[i][j]<<endl;
// cout<<qu(N)+cnt0<<endl;
ans+=ssum+cnt0;
}
}
}
for(int i=l;i>=1;i--){
for(int j=0;j<vec[i].size();j++){
int k=vec[i][j];
if(k!=0)
add(k,-1);
}
}
for(int i=0;i<=l+2;i++){
vec[i].clear();
v1[i].clear();
}
write(ans);
putchar('\n');
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...