選択されたメモリコンテンツ検索撥のP3172は、[CQOI2015] +数

P3172 [CQOI2015] Numberから選択

タグ

  • インクルージョン排除
  • メモリ検索

序文

  • 良い質問 - 反転デュ画面の後に教えることができる、あなたは、次の式のDPをプッシュすることができます!

質問の簡潔な意味

  • 所与\(N、K、L、R&LT \) あなたが要求間隔から、取得する必要があり、\([L、R]は\ ) で選択されている\(N- \)数およびそれらの\(GCD = K \ )プログラムの数。(繰り返し数は、選択されました)

考え

  • 我々は、サンプルのセットと仮定する\(= N-2、K = 3、L = 2、10 = R&LTの\) だから我々はから必要な\([2,10] \)彼らの作る、2つの数値を選択するために、\(GCD = 2 \)を1つの明らかな事は、我々が選択した方法に関係なく、これらの特定の数がされて選択することです\(k個\)倍数。
  • 我々は、サンプルは、K = 3,6,9は、3の倍数であり、数がされているものと仮定することがわかっ(X \)\\(X = 3 \) 私たちは、すべてのオプションの合計リスト\(X ^ N = 3 ^ 2 = 9 \) (3,3)、(3,6)、(3,9)、(6:プログラムの種類があります、3)、(6,6)、(6,9)、(9,3)、(9,6)、(9,9)。明らかに、いくつかあります\(GCDの\)どうやら3、いくつかの6、いくつかさえ9があります。
  • 今設定\(F(i)を\)所与のため\(N、K、L、R&LT \)を選択するために、\(N-を\)数との\(GCD = iが\)プログラムの数。依然として上記の実施例によると、\(F(2)= ^ 2 3-F(6)-f(9)\)この式が来るかについて疑問)。そう順序\(X = [L、R ] \) で\(Iは\)の数倍は、上記の実施例に従って、知っていることは容易である
    \ [F(I)= X ^ NFを(2 * I) -f(3 * I)-...- F (m個* i)を(Mの* I <= R)\]

    ここでのxを見つけるための方法について話をします。\(X = \ FRAC RI-の\ FRAC-L {I}。1 \) それらを知っているように、この式は例示することができる方法

  • これは、明らかに、再帰的である場合\(K = 1、R = 1E9の\) 、再帰定数T. これは、最適化しました。:ブレークスルーが文に最適化された(HLの<= 10 5 ^ \)\その後、我々は重要な特性を持っていますから\([L、R] \ ) 、いくつかの異なる番号を選択し、彼らは(GCD \)\超えない\(RL \を)私たちの本質を知っている\を(F(x)は\)することはできません\(fは(2 * I) \) 口座に入れてきた(F(m個* i)を\ \(のm * I <= R)) 、ので\(iは\ M *)は、単純にすることができない(GCD \)\ようにのみ、\(F(2 * I) \) を考慮に入れて\(F(m個* i)を (Mの* I <= RL )\)が、それはほとんど変化が必要です。
  • メモリ\(F(I)\)選択された場合の同じ番号が含ま定義されます。あなたは上記を使用できるようにだから我々は、様々な状況の数を計算することを選択したと述べた\(GCDの\)文字は、単純に最後のプログラムの同じ数を引くの数を選択し、。N = 1、pがN> = 2、我々は区間kの[L、R]の複数を考慮する必要がある場合、明らかに0であり、数学的な計算を組み合わせしかしトラブルの多くは、数は、同じプロトコル集合Pです。多くの問題。簡略化された方法があります:
  • Lに直接であり、kで割ったRは、それはGCD == 1、内の新しいセクションのプログラムの数を見つけることになります。この後、計算を繰り返すプロトコルの要素の数は、L = 1、K = 1であるため、唯一の素数1、そう要素が1つだけ繰り返すことができ、非常に良好である限り、新規及び2以上の数を選択すること、その後、プログラム番号1に、それは簡単です。

注意事項

  • 直接減算法と間違って行く、我々は別のモジュール剰余を追加する必要があります

概要

  • \([L、R] \ ) 異なる数の複数を選択し、それらの\(GCD \)を超えていない\(RL \)を

ACコード

#include <cstdio>
#include <unordered_map>
using namespace std;

const int mod = 1000000007;

int ksm(int a, int b) {
    int base = a, ans = 1;
    while (b) {
        if (b & 1)
            ans = 1ll * ans * base % mod;
        base = 1ll * base * base % mod;
        b >>= 1;
    }
    return ans;
}

int n, k, l, r;
unordered_map<int, int> rec;

int f(int k) {
    if (rec[k] != 0)
        return rec[k];
    int x = r / k - (l - 1) / k;
    int ans = ksm(x, n) - x;

    for (int i = 2; i * k <= r - l; i++) ans = (ans - f(i * k) + mod) % mod;

    return rec[k] = ans;
}

void solve() {
    scanf("%d%d%d%d", &n, &k, &l, &r);
    l = (l % k == 0 ? l / k : l / k + 1);
    r /= k;
    k = 1;

    printf("%d", f(k) + (l == 1 && n >= 2));
}

int main() {
    solve();
    return 0;
}

おすすめ

転載: www.cnblogs.com/danzh/p/11299393.html