3356. 解方程

单点时限: 2.0 sec
内存限制: 256 MB
简而言之,本题任务就是解方程。共有两个子任务。
子任务 1:小学生
作为小学生,我们只会解一元一次方程,一元一次方程最终都可以化为 ax=n 的形式。现在问:对于给定的 n,要使得 x 有正整数解,总共可以取多少个不同的 a 呢?
子任务 2:中学生
作为中学生,我们只会解二元一次不定方程,二元一次不定方程最终都可以化为 ax+by=n 的形式。现在问:对于给定的 n,要使得 x,y 有正整数解,总共可以取多少对不同的 (a,b) 呢?
输入格式
输出一行两个整数 q,n (q∈{1,2})。
q=1 表示你现在要解决小学生的情况,q=2 表示你现在要解决中学生的情况。
数据规模约定(每个测试点占本题总分值的 10%):
【3356. 解方程】测试点 q n
1 =1 1≤n≤1 000
2, 3 =1 1≤n≤300 000
4, 5 =2 1≤n≤50
6, 7 =2 1≤n≤500
8, 9 =2 1≤n≤50 000
10 =2 1≤n≤300 000
输出格式
输出一个整数,表示答案。
样例
input
2 4
output
6
input
1 10
output
4
提示
当 q=1,n=10 时,a 可以取 1,2,5,10。
当 q=2,n=4 时,(a,b) 可以取 (1,1),(1,2),(1,3),(2,1),(2,2),(3,1)。
****方法一:
扩展欧几里得算法得:ax+by=n有解的充要条件为:
n%gcd(a,b)==0
可一个一个枚举,在验证x,y是否为整数。此方法超时了。
方法二:
枚举n-ax=t,t=by。枚举t的公约数b。此时(a,b)为解,用visit[b]=a表示计算过了。

//方法一 #include #include #include using namespace std; int f(int n) { int ans=2; for(int i = 2; i<=n/2; i++) { if(n%i==0) ans++; } return ans; } bool text(int n,int a,int b) { for(int i = 1; i*b < n; i++) if((n-i*b) % a == 0) return true; return false; } int count(int n) { int ans=0; for(int i = 1; i < n; i++) { for(int j=1; j <=n-i; j++) { if(n%__gcd(i,j)==0&&text(n,i,j)) { ans++; } } } return ans; } int main() { int q,n; cin>>q>>n; if(q==1) { cout<

//方法二: #include #define ll long long using namespace std; int q,n; int a,b; vector num[300005]; int visit[300005]; int main() { scanf("%d %d",&q,&n); if(q==1) { int ant=0; for(int i=1; i<=n; i++) { if(n%i==0) { ant++; } } printf("%d\n",ant); } else { int ans=0; for(int i=1; i

    推荐阅读