简而言之,本题任务就是解方程。共有两个子任务。
子任务 1:小学生
作为小学生,我们只会解一元一次方程,一元一次方程最终都可以化为 ax=n 的形式。现在问:对于给定的 n,要使得 x 有正整数解,总共可以取多少个不同的 a 呢?
子任务 2:中学生
作为中学生,我们只会解二元一次不定方程,二元一次不定方程最终都可以化为 ax+by=n 的形式。现在问:对于给定的 n,要使得 x,y 有正整数解,总共可以取多少对不同的 (a,b) 呢?
Input
输出一行两个整数 q,n (q∈{1,2})。
q=1 表示你现在要解决小学生的情况,q=2 表示你现在要解决中学生的情况。
数据规模约定(每个测试点占本题总分值的 10%):
测试点 | 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 |
Output
输出一个整数,表示答案。
Examples
input
2 4
output
6
input
1 10
output
4
Note
当 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)。
思路:第一个直接枚举,第二个先找出每个数的因子,然后去找解,居然跑过了(泪,流了下来)
#include <bits/stdc++.h> #define ll long long using namespace std; int q,n; int a,b; vector<int> num[300005]; int vis[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 ",ant); } else { int ant=0; for(int i=1;i<n;i++) { num[i].clear(); for(int j=1;j*j<=i;j++) { if(i%j==0) { num[i].push_back(j); if(j*j!=i) num[i].push_back(i/j); } } sort(num[i].begin(),num[i].end(),greater<int>()); } memset(vis,0,sizeof(vis)); for(int q=1;q<n;q++) { for(int x=1;x<n;x++) { if(q*x>=n) break; int t=n-q*x; for(int i=0;i<num[t].size();i++) { if(vis[num[t][i]]!=q) { ant++; vis[num[t][i]]=q; } } } } printf("%d ",ant); } return 0; }