joxjシミュレーションゲーム2019年9月3日

joxjシミュレーションゲーム2019年9月3日

タイトルゲーム出典:2018qbxt合肥1日目

最小公倍数T1

問題の意味:既知の正の整数n、およびnの最小公倍数 - 246 913 578、モジュロ1234567890結果

データ範囲:. 1 <= N <10 = 100000

LCM = A * B / GCD(a、b)は(MOD 1234567890)

私たちは、逆数を考慮すると、大きな除数剰余必要性を見つけましたが、B、1234567890必ずしも互いに素ので、逆数を使用することはできません

しかしながら、GCDの性質に、GCD(A、B)= GCD(%のB、B)、また、複数のBのモジュラスことが見出され、

このため、高精度に直接読み取られるモジュロであることができる:GCD(A、B)= GCD(%1234567890、B)

しかし、検査はあまり考えていなかったとき、あまりにも厳格A、結論を直接解く推測

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
ll mol;
ll gcd(ll a, ll b)
{
    return (b == 0)? a : gcd(b,a%b);
}
ll lcm(ll a, ll b)
{
    return ((a * b)  / gcd(a,b)) % mol;
}
char ch[100100];
int main()
{
    mol = 1234567890;
    ll n = 0, m = 246913578; scanf("%s",ch + 1);
    ll len = strlen(ch + 1); ll rest = 0;
    ll alen = len; ll x = 1e9;
    while(len > 8)
    {
        ll now = 0;
        for(int i = alen - len + 1; i <= alen - len + 8; i++)
        {
            now = now * 10 + ch[i] - '0';
        }
        rest = (now + ((rest * x)% mol)) % mol;
        len -= 8;
    }
    for(int i = alen - len + 1; i <= alen; i++)
    {
        n = n * 10 + (ch[i] - '0');
    }
    n = n % mol;
    n = ((rest * x) % mol + n) % mol;
    printf("%lld\n", lcm(n, m));
    return 0;
}

不可逆的なT2

この質問にはロスバレーがありますトピックのリンクを

配置が変動するように構成されている数Nを満たし、応答モジュロMを見つけるために1:問題の意味。

データ範囲:. 1 <= N - <=千メートル<= 10 9。

この質問は、波のシーケンスを解決するようLCISビットと最初の一目で見て感じることですが、すぐに大きな違いを発見し、この質問には、1つの配列のみであり、波のシーケンスその質問は、2つの配列です。私はそれが何の式が存在しない、この質問を見て、テーブルを打つ考え始めたが、長いを探したり、法律を見つけることができませんでしたので、私は、この質問は、道路DP見つけることができる一瞬思ったが、私は長い時間のためだと思いますか私はトラブルの暴力的な検索と呼ばれる、DPのためにこの質問の特別な性質を期待していませんでした。

案の定、すべての方程式は次のようにこの質問の性質に関係しているDPと話題の性質を記述することは困難です。

配列は、nに1に離散化することができることは、通常の配列について1は、配置されています。

「揺らぎ」の程度は、2配列が配列番号特性を説明するときに使用されるパラメータの一つです。

nに装置1を考慮すると、位置の最大数は、「ゆらぎ」配列の程度を表すと考えることができます。

我々はまた、配列の最初の低下を発見した後、各数値は、2つの配列を交換するためのn + 1-Xに配列Xのいずれかとすることができる、配列を減少させました。

だから、私たちは、プログラムはその後、* 2が可能な数の一つの配列を数えるだけです。

F [I]を算出する際に、iは位置jは、jは二つの部分に配列が、プログラムが原因の性質1に、位置の数を算出列挙子、我々は、から選択される左側(左組成の数の選択された最初の数を乗算する必要がありますこれはまた、決定され、右から選択された数の数を決定する)、次いで、C(I-1、J-1)* F [J-1] * [IJ]にF。

動的に最適化された空間アレイに使用することができます。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, m;
long long C[1010][1010]={},f[1010]={};
int main()
{
    scanf("%d%d", &n, &m);
    C[0][0] = 1;
    for(int i = 1; i <= n; i++)
    {
        C[i][0] = 1;
        for(int j = 1; j <= i; j++)
        {
            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % m;
        }
    }
    f[0] = 1; f[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        for(int j = 1; j <= i; j++)
        {
            if(j&1) f[i] = (f[i] + (((f[j - 1] % m) * (f[i - j] % m)) % m) * C[i - 1][j - 1]) % m;
        }
    }
    printf("%d\n",f[n] * 2 % m);
    return 0;
}

数値微分

意题: 、 F 0 = 、 F(X) 、 F I = 0 、 F I = 、 F I-1 - 、 F I-1

第一行動nの入力、第二行動F(I)、Fとの出力のM nは数M、モジュロ100007結果

データ範囲:. 1 <= N - <= 1000 1 <= M <= 10 。9 0 <= F [I] <100007

この質問はパスカルの私が検査中に発見されたトライアングルが、実行する時間がないですが、また、パスカルの三角形との組み合わせの数をカウントするために期待していませんでした。

まず、我々は、その配列の存在を疑いのF M = [0] * F [I-0] + [1] * F [I-1] + ... + [-I 1] * F [I-( I-1)]

- (1)を見つける= A Jので、この前* C(M、j)は、質問は、>我々は、nとき> mは時間の現在の数は、最初のm数に影響を与えている見つけるのですかmをnとし、組み合わせの数に直接数初期値0を乗算することができる、と回答には影響しませんので、我々は唯一の最小値nとmの缶に行く必要があります。

この質問はまた、ピット100007は、拡張子のみルーカス定理を使用し、それはルーカスの定理を使用することはできません、素数ではありません

我々は(このステップはまた、多くの詳細である)、そして、あなたが直接計算することができ、品質係数の分解の組み合わせの数を分子と分母ます。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define mol 100007
#define ll long long
int n, m;
ll C[1010];
int fac[1010]={};
ll f[1010];
ll rest = 1;
void dvd(int x,int k)
{
    for(int i = 2; i <= n; i++)//
    {
        while(x % i == 0)
        {
            fac[i] += k; x /= i;
        }
    }
    if(x != 1)rest = (rest * (x % mol)) % mol;//
}
ll quickpow(ll a, int b)
{
    ll ret = 1;
    while(b != 0)
    {
        if(b&1) ret = ret * a % mol;
        a = a * a % mol;
        b >>= 1;
    }
    return ret;
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)scanf("%lld", &f[i]);
    C[0] = 1;
    for(int i = 1; i <= min(m, n); i++)
    {
        C[i] = 1;
        dvd(m - i + 1, 1); dvd(i, -1);
        C[i] = C[i] * rest % mol;
        for(ll j = 2; j <= n; j++)
        {
            if(fac[j] != 0)
            {
                C[i] = (C[i] * quickpow(j, fac[j])) % mol;
            }
        }
        //printf("C[%d] = %d\n", i, C[i]);
        //for(int i = 1; i <= min(m, n); i++)printf("fac[%d] = %d\n", i, fac[i]);
    }
    for(int i = 1; i <= n; i++)
    {
        ll ans = 0;
        for(int j = 0; j < i; j++)
        {
            if(j&1)
            ans = ((ans + (f[i - j] * C[j]) % mol * (-1)) % mol + mol) % mol;
            else
            ans = (ans + (f[i - j] * C[j]) % mol) % mol;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/Akaina/p/11455761.html