社区讨论

求hack

P3082[USACO13MAR] Necklace G参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mhizrheb
此快照首次捕获于
2025/11/03 18:22
4 个月前
此快照最后确认于
2025/11/03 18:22
4 个月前
查看原帖
奇妙的做法,如果把匹配的地方改成其他线性整体就是线性了(也交过哈希的),但感觉会假却又能过
CPP
#include<bits/stdc++.h>
namespace yycio{
inline int read(){
	char c=getchar();
	int x=0,f=1;
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while('0'<=c&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
	return x*f;
}
inline void print(int x){
	if(x==0){putchar('0');return;}
	if(x<0)putchar('-'),x=-x;
	char num[40];
	int len=0;
	while(x)num[len++]='0'+(x%10),x/=10;
	while(len--)putchar(num[len]);
}
};
using namespace yycio;
using namespace std;
const int N=5e4+5;

char s[N],t[N];
bool tag[N];
int l[N],r[N],tot;

inline int solve(int l,int r){
	int cnt[2]={0,0};
	for(int i=l;i<=r;i++)++cnt[s[i]==t[2]];
	int ct[2]={0,0};
	int res=min(cnt[0],cnt[1]);
	for(int i=l;i<=r;i++){
		++ct[s[i]==t[2]];
		res=min(res,ct[0]+(cnt[1]-ct[1]));
	}
	return res;
}

signed main(){
	scanf("%s",s+1);
	scanf("%s",t+1);
	int n=strlen(s+1),m=strlen(t+1);
	int cnt=0,x1=0,x2=0;
	for(int i=1;i<m;i++)
	if(t[i]!=t[i+1]){
		++cnt;
		if(!x1)x1=i;
		x2=i;
	}
	if(!cnt){
		int ans=n;
		for(int i=1,cnt=0;i<=n;i++){
			if(s[i]!=t[1])cnt=0;
			else{
				++cnt;
				if(cnt>=m)--cnt,--ans;
			}
		}
		print(n-ans);
	}else if(cnt==1){
		int ans=n;
		for(int i=1;i+m-1<=n;i++){
			for(int j=1;j<=m;j++)
			if(s[i+j-1]!=t[j])goto aaa;
			tag[i]=1;
			aaa:;
		}
		if(m==2){
			for(int i=1,l=1;i<=n+1;i++)
				if(s[i]!=t[1]&&s[i]!=t[2]){
					if(l<i-1)ans-=solve(l,i-1);
					l=i+1;
				}
		}else{
			for(int i=1;i+m-1<=n;i++){
				if(tag[i]){
					int l=i,r=i+m-1;
					while(l>1&&s[l-1]==s[l])--l;
					while(r<n&&s[r+1]==s[r])++r;
					if((x1>1||!tag[l-m])&&(x1+1<m||!tag[r+1])){
						ans-=min(i-l+1,r-i+1-m+1);
					}else if(x1>1||!tag[l-m])ans-=i-l+1;
					else if(x1+1<m||!tag[r+1])ans-=r-i+1-m+1;
				}
			}
		}
		print(n-ans);
	}else{
		int ans=n;
		for(int i=1;i+m-1<=n;i++){
			for(int j=1;j<=m;j++)
			if(s[i+j-1]!=t[j])goto bbb;
			++tot;
			l[tot]=i,r[tot]=i+m-1;
			if(s[i-1]==s[i])l[tot]=i+x1;
			if(s[i+m]==s[i+m-1])r[tot]=i+x2-1;
			bbb:;
		}
		for(int i=1,now=0;i<=tot;i++)
			if(now<l[i])--ans,now=r[i];
		print(n-ans);
	}
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...