传送门:http://codeforces.com/contest/1089/problem/F
思路:发现两个数字就可以凑出一个合数,变成ax+by=n-1求解,妙啊(后来发现不用欧几里得,暴力也可以……??)
代码:
#include<bits/stdc++.h>
using namespace std;
using ll=long long ;
const ll maxn=1e5+6;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1;
y=0;
return a;
}
ll g=exgcd(b,a%b,x,y);
ll tmp=x;
x=y;
y=tmp-a/b*y;
return g;
}
int main(){
ll n;
while(~scanf("%lld",&n)){
ll flag=0;
for(ll i=2;i*i<=n;i++){
if(n%i==0){
ll a=i;
ll b=n/i;
ll g=gcd(a,b);
if(a!=b&&(n-1)%g==0){
ll x,y;
ll tmp=exgcd(a,b,x,y);
//cout<<"tmp: "<<tmp<<" x: "<<x<<" y: "<<y<<endl;
ll xx=(n-1)*x/g;
ll yy=(n-1)*y/g;
//cout<<" xx: "<<xx<<" yy: "<<yy<<endl;
while(xx<0){
xx+=b/g;
yy-=a/g;
}
while(yy<0){
xx-=b/g;
yy+=a/g;
}
if(xx < 0 && yy < 0)
{
continue;
}
printf("YES\n2\n%lld %lld\n%lld %lld\n",yy,a,xx,b);
flag=1;
break;
}
}
}
if(!flag){
printf("NO\n");
}
}
}