Title

P9703 「TFOI R1」Average Number 题解

题目大意

已知 $\frac{(\sum^{n}_ {i}i)-m}{n-1}=a+\frac{b}{c}$ 和 $a$、$b$、$c$,求出 $n$、$m$ 且 $n$ 最小的解。

解题思路

其实这道题并不难,主要是分类讨论比较麻烦,大体思路如下:

$\because \frac{(\sum^{n}_ {i}i)-m}{n-1}=\frac{n}{2}+\frac{n-m}{n-1}=a+\frac{b}{c}$

$\therefore$ 即为求 $\frac{n}{2}+\frac{n-m}{n-1}=a+\frac{b}{c}$ 的 $n$ 最小的解。

$\therefore$ 易想到,分类讨论,首先分为两大点讨论:$b$ 为 $0$ 和 $b$ 为 $1$。

一:当 $b$ 为 $0$ 的时候,$\frac{n}{2}+\frac{n-m}{n-1}$ 为整数。

  1. 当 $n$ 能够整除 $2$ 时,有 $n-m$ 整除 $n-1$。此时,当 $n-m$ 等于 $0$ 时,$n=2a$,当 $n-m=n-1$ 时,$n=2a-2$,显然,$n=2a-2$ 比 $n=2a$ 更优,所以,我们优先考虑取 $n=2a-2$。解出后带入原式,判断 $m$ 是否小于等于 $n$ 且大于等于 $1$,如果不满足条件,那么就取 $n=2a$ 并求解。
  2. 当 $n$ 不能够整除 $2$ 时,那么 $n=2k+1$,此时 $\frac{n-m}{n-1}=\frac{1}{2}$,$n=2a-1$,没有 $2=2a-2$ 优,舍去。

二:当 $b$ 不为 $0$。

  1. 当 $n=2k-1$,$m=\frac{((c-2b)n+2b+c)}{2c}$,同样,算完后带入检验,如果不满足条件,直接舍去。
  2. 当 $n=2k$,$m=\frac{n-b(n-1)}{c}$,算完后检验。
  3. 当 $n=2k+1$,$m=\frac{((3c-2b)n+2b-c)}{2c}$,计算后带入检验

综上所述,总共分为两大类五小类讨论,按照 $n$ 从小到大的顺序讨论即可,因为保证有解,所以不需要考虑无解的情况。

AC代码

#include<bits/stdc++.h>
#define ull usigned long long
using namespace std;
const string TypideName="c";
inline void readc(char &c){
    c=getchar();
    while(c==' '||c=='\n')
        c=getchar();
}inline void writec(char c){putchar(c);}
template<typename T>inline void read(T& x) {
    if(typeid(x).name()==TypideName){char ch;readc(ch);x=ch;return;}
    x = 0; bool f = false; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-') f = !f; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
    x = (f ? -x : x); return;
}template<typename T>inline void put(T x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) put(x / 10);
    putchar(x % 10 + '0'); return;
}template<typename T>inline void write(T x) {
    if(typeid(x).name()==TypideName){writec(x);return;}
    put(x);
}
template<typename T,typename... Args>
inline void read(T& x,Args&...x_) {read(x),read(x_...);}
template<typename T,typename... Args>
inline void write(T x,Args...x_){write(x),write(x_...);}
inline void read(__int128 &x){
    x = 0; bool f = false; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-') f = !f; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
    x = (f ? -x : x); return;   
}inline void put(__int128 x){
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) put(x / 10);
    putchar(x % 10 + '0'); return;  
}inline void write(__int128 x){put(x),putchar(' ');return;}
#define ll __int128
inline ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
ll a,b,c,n,m;
inline void work(){
    read(a),read(b),read(c);
    if(b==0){ 
        n=(a<<1)-2,m=1;
        if(m<1||m>n){
            n=(a<<1),m=n;
        }
        write(n);
        write(m);putchar('\n');
        return;
    }
    bool is=true;
    n=(a<<1)-1;
    if(((c-(b<<1))*n+(b<<1)+c)%(c<<1)!=0) is=false;
    if(is){
        m=((c-(b<<1))*n+(b<<1)+c)/(c<<1);
        if(2*(n-m)<=(n-1)||m<1||m>n) is=false;
        if(is){
            write(n),write(m);
            putchar('\n');return;
        }
    }is=true;
    n=a<<1;
    if((b*(n-1))%c!=0) is=false;
    if(is){
        m=n-b*(n-1)/c;
        if(m<1||m>n) is=false;
        if(is){
            write(n),write(m);
            putchar('\n');return;
        }
    }is=true;
    n=(a<<1)+1;
    if(((3*c-2*b)*n+2*b-c)%(c<<1)!=0) is=false;
    if(is){
        m=((3*c-2*b)*n+2*b-c)/(c<<1);
        if(2*(n-m)>=(n-1)||m<1||m>n) is=false;
        if(is){
            write(n);write(m);
            putchar('\n');return;
        }
    }
}
signed main(){
    int T;read(T);
    while(T--) work();
    return 0;
}
posted @ 2023-10-09 14:05  UncleSam_Died  阅读(15)  评论(0)    收藏  举报  来源