社区讨论

请求加强数据

P9453 [ZSHOI-R1] 有效打击参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lo2aggtm
此快照首次捕获于
2023/10/23 10:38
2 年前
此快照最后确认于
2023/11/03 10:49
2 年前
查看原帖
我在比赛里面交了一个错漏百出的代码结果只wa了第10个点,挺意外的
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
#define N 5000005
ll n,m,nn,mm;
int a[N],b[N],ac[N],bc[N];
ll ah[N],bh[N];
int bf[N],bhf[N];
ll gcd(ll x,ll y){
	if(y==0)return x;
	return gcd(y,x%y);
}
ll workhash(ll x,ll y){
	ll g=gcd(x,y);
	x/=g,y/=g;
	return x*N+y;
}
int main(){
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>nn>>mm;
	{
		ll last=0;
		for(int i=1;i<=nn;i++){
			ll x;
			cin>>x;
			if(x!=last){
				last=x;
				a[++n]=x;
				ac[n]=1;
			}
			else ac[n]++;
		}
	}
	{
		ll last=0;
		for(int i=1;i<=mm;i++){
			ll x;
			cin>>x;
			if(x!=last){
				last=x;
				b[++m]=x;
				bc[m]=1;
			}
			else bc[m]++;
		}
	}
	if(m==1){
		ll ans=0;
		for(int i=1;i<=n;i++){
			if(a[i]==b[1])ans+=(ac[i]*(ac[i]+1ll))>>1;
		}
		cout<<ans;
	}
	else if(m==2){
		ll ans=0;
		ll bc1=bc[1],bc2=bc[2];
		ll g=gcd(bc1,bc2);
		bc1/=g,bc2/=g;
		for(int i=1;i<n;i++){
			if(a[i]==b[1]&&a[i+1]==b[2]){
				ans+=min(ac[i]/bc1,ac[i+1]/bc2);
			}
		}
		cout<<ans;
	}
	else if(m==3){
		ll ans=0;
		ll bc1=bc[1],bc2=bc[2],bc3=bc[3];
		ll g=gcd(gcd(bc1,bc2),bc3);
		bc1/=g,bc2/=g,bc3/=g;
		for(int i=2;i<n;i++){
			if(a[i-1]==b[1]&&a[i]==b[2]&&a[i+1]==b[3]){
				if(ac[i]%bc2==0){
					ll mul=ac[i]/bc2;
					if(bc1*mul>=ac[i-1]&&bc2*mul>=ac[i+1])ans++;//错误1:右端点的判断完全写错了
				}
			}
		}
		cout<<ans;
	}
	else{
		//get ah,bh
		for(int i=1;i<=n-1;i++)ah[i]=workhash(ac[i],ac[i+1]);
		//for(int i=1;i<=n-1;i++)cout<<ah[i]<<" ";cout<<"\n";
		for(int i=1;i<=m-2;i++)bh[i-1]=workhash(bc[i],bc[i+1]);
		//for(int i=1;i<=m-1;i++)cout<<bh[i]<<" ";cout<<"\n";
		//get f for b,bh
		{
			ll j=0;
			for(int i=2;i<=m;i++){
				while(j>0&&b[i]!=b[j+1])j=bf[j];
				if(b[i]==b[j+1])j++;
				bf[i]=j;
			}
		}
		{
			ll j=0;
			for(int i=2;i<=m-2;i++){
				while(j>0&&bh[i]!=bh[j+1])j=bhf[j];
				if(bh[i]==bh[j+1])j++;
				bhf[i]=j;
			}
		}
		//kmp a,b
		vector<int> v1;
		{
			ll j=0;
			for(int i=1;i<=n;i++){
				while(j>0&&a[i]!=b[j+1])j=bf[j];
				if(a[i]==b[j+1])j++;
				if(j==m){
					v1.push_back(i-m+1);
					j=bf[j];
				}
			}
		}
		//kmp ah,bh
		vector<int> v2;
		{
			ll j=0;
			for(int i=1;i<=n-1;i++){
				while(j>0&&ah[i]!=bh[j+1])j=bhf[j];
				if(ah[i]==bh[j+1])j++;
				if(j==m-3){
					v2.push_back((i-(m-3)+1)-1);
					j=bhf[j];
				}
			}
		}
		
		//for(int i=0;i<v1.size();i++)cout<<v1[i]<<" ";cout<<"\n";
		//for(int i=0;i<v2.size();i++)cout<<v2[i]<<" ";cout<<"\n";
		//merge ans
		{
			ll ans=0;
			
			ll g=bc[1];
			for(int i=2;i<=n;i++)g=gcd(g,bc[i]);
			for(int i=1;i<=n;i++)bc[i]/=g;
			ll s1=v1.size(),s2=v2.size(),i1=0,i2=0;
			while(i1<s1&&i2<s2){
				if(v1[i1]==v2[i2]){
					{
						ll i=i1;//错误2:应为v1[i1]
						if(ac[i+1]%bc[2]==0){
							ll mul=ac[i+1]/bc[2];
							if(bc[1]*mul>=ac[i]&&bc[m]*mul>=ac[i+m-1])ans++;//错误3:符号写反了
						}
					}
					i1++;i2++;
				}
				else if(v1[i1]>v2[i2])i2++;
				else i1++;
			}
			cout<<ans;
		}
	}
	return 0;
}

回复

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

正在加载回复...