【数学】解方程

简而言之,本题任务就是解方程。共有两个子任务。

子任务 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 1n1 000
2, 3 =1 1n300 000
4, 5 =2 1n50
6, 7 =2 1n500
8, 9 =2 1n50 000
10 =2 1n300 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\n",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\n",ant);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Diliiiii/p/9831580.html