zoukankan      html  css  js  c++  java
  • Comet OJ

    题目链接:

    https://www.cometoj.com/contest/65/problem/C

    题意:

    找到最小的前n项和 使得 该前n项和 mod 给出的 X 等于 0

    思路:

    看到这个方程的话就会想到 (n+1)*n/2 % X = 0 ,即 (n+1)*n %2X =0; 与余数相关的,比如同余方程之类的。当然也会想到 exgcd()求相关的问题

    ax+ ny= b 方程最小正整数解
    ax≡b(mod n) 求逆元原理(同余方程)
    ax+by=gcd(a,b) (a,b互质才有解)

    设 n+1 = ap, n= bq,联立得到方程:qp - bq = 1 ,要求 bq 的最小解,经典的扩展欧几里得问题。
    方程有解条件必须满足 gcd(a,b)==1 ,所以通过唯一分解定理分解该数,然后为了满足互质即取所有质因子的 全部幂作为乘积。
    code:

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #define IOS ios::sync_with_stdio(0); cin.tie(0);
    #define mp make_pair
    #define Accept 0
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    const double Pi = acos(-1.0);
    const double esp = 1e-9;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e5+7;
    const int maxm = 1e6+7;
    const int mod = 1e9+7;
    const int MAXL = 1e6+7;
    
    int prim[MAXL];
    int cnt;
    ll fac[MAXL];
    int vis[MAXL];
    int cur;
    ll mx;//该数质因子的幂的最大次数 
    
    int getPrime(){
        int i ,j;
        int cnt = 0;
        memset(vis,0,sizeof(0));
        vis[0] = vis[1] = 1;
        for(i=2;i<=MAXL;++i)
        {
            if(!vis[i]) vis[i]= prim[cnt++]= i;
            for(j=0;j<cnt&&i*prim[j]<=MAXL;++j){
                vis[i*prim[j]] = 1;
                if(i%prim[j]==0) break;
            }
        }
        return cnt;
    }
    ll exgcd(ll a, ll b, ll &x, ll &y) {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        ll d = exgcd(b,a%b,x,y),temp = x;
        x = y;
        y = temp-a/b*y;
        return d;
    }
    int getFactor(ll n,int cnt){
        int cur = 0;
        for(int i=0;i<cnt;i++){
            if(n==1) break;
            if(n%prim[i]==0){
                fac[cur] = 1;
                while(n%prim[i]==0){
                    n /= prim[i];
                    fac[cur] *= prim[i];
                }
                cur++;
                mx = max(mx,fac[cur]);
            }
        }
        if(n>1) fac[cur++] =n;return cur;
    }
    
    ll solve(ll n){
            ll ans = n<<1;
        //有那么多个互质质因子组成种可能 
        for(int i=1;i<(1<<(cur));i++){
            ll a = 1,b;
            for(int j=0;j<(cur);j++){
                if(i&(1<<j)) a *= fac[j];
            }
            b = 2*n /a;
            ll x,y;
            exgcd(a,b,x,y);
            ans=min(ans,min(-((x%b+b)%b-b)*a,-((y%a+a)%a-a)*b));
    //        exgcd(a,b,x,y);
    //        ll xx=x,yy=y;
    //        if(x>0){
    //            x = xx%b;
    //            y += (xx-x)/b*a;
    //        }else{
    //            y = yy%a;
    //            x += (yy-y)/a*b;
    //        }
    //        ans = min(ans,min(abs(a*x),abs(b*y)));    
        }
        return ans;
    }
    int main(){
        int T;
        cnt = getPrime();
        cin>>T;
        //设x+1 = ap,x = bq; 可得ap-bq = 1;
        //求bq的最小解 ,exgcd();
        while(T--){ 
            ll n; scanf("%lld",&n);
            n <<= 1 ;
            cur = getFactor(n,cnt);
            ll ans = solve(n/2); 
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    poj 1262 地板覆盖问题
    混合图 (Standard IO)
    matrix
    麻将 (Standard IO)
    C#多线程编程之:异步事件调用
    使用线程池与专用线程
    C#多线程编程之:Timer(定时器)使用示例
    C#多线程编程之:异步方法调用
    WCF 快速入门
    c#实现每隔一段时间执行代码(多线程)
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11482380.html
Copyright © 2011-2022 走看看