根据同余模的性质,取模后的结果在进行加和乘之后再取模,与取模前的结果进行加和乘之后再取模结果相同。
要把一个数分为两个部分,左半部分能被a整除,右半部分能被b整除。
我们可以做一个预处理,用dp1[i]表示从最左开始到第i位组成的数模a的值,用dp2[i]表示从最后开始到第i为组成的数模b的值。
然后我们需要找到一个0<i<len-1,使得该位置后面一位不是0(防止前导0),且dp1[i]=dp2[i+1]=0;
#include <cstdio>
#include <cstring>
char a[1000100];
long long dp1[1000100];
long long dp2[1000100];
int main(){
scanf("%s",a);
int x,y;
scanf("%d%d",&x,&y);
int size=(int)strlen(a);
dp1[0]=(a[0]-'0')%x;
for(int i=1;i<size;++i){
dp1[i]=(dp1[i-1]*10+a[i]-'0')%x;
}
dp2[size-1]=(a[size-1]-'0')%y;
long long sign=1;
for(int i=size-2;i>=0;--i){
sign=sign*10%y;
dp2[i]=(dp2[i+1]+(a[i]-'0')*sign)%y;
}
int i;
for(i=0;i<size-1;++i){
if(dp1[i]==0&&dp2[i+1]==0&&a[i+1]!='0'){
break;
}
}
if(i==size-1){
printf("NO\n");
}
else{
printf("YES\n");
for(int j=0;j<=i;++j){
printf("%c",a[j]);
}
printf("\n");
for(int j=i+1;j<size;++j){
printf("%c",a[j]);
}
printf("\n");
}
return 0;
}