首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

ZOJ 3785 What day is that day?:模 7 週期性求星期幾

     編輯:C++ 入門

問題描述

今天是星期六。求經過 S = 1^1 + 2^2 + ... + N^N 天後是星期幾。N ≤ 109,多測試用例。

關鍵觀察:模 7 週期性

星期循環週期 7。需計算 S mod 7。觀察 i^i mod 7 的序列:

  • i mod 7 週期 7
  • i mod 6 決定冪次模 7(費馬小定理:a^6 ≡ 1 (mod 7) 對 7∤a)
  • 綜合週期為 lcm(7, 6) = 42?實際驗證 i^i mod 7 週期為 42?不,代碼中用 294 = 7 × 42?

經測試/打表發現:i^i mod 7 序列週期為 294(= 7 × 6 × 7?實際為 lcm(7, φ(7)) × 7?)。前綴和 S(N) mod 7 也週期 294。

預計算表


int period = 294;
int sum[period+1];
sum[0] = 0;
for (int i=1; i<=period; ++i) {
    int p = 1;
    for (int j=0; j

查詢答案

day = sum[N % period],映射到星期名稱:0:Saturday, 1:Sunday, ..., 6:Friday。

代碼實現


#include 
const char* day[7] = {"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};
int sum[295];

int powmod(int a, int n, int mod) {
    int r = 1;
    while (n) {
        if (n&1) r = r*a % mod;
        a = a*a % mod;
        n >>= 1;
    }
    return r;
}

int main() {
    sum[0] = 0;
    for (int i=1; i<=294; ++i) {
        sum[i] = (sum[i-1] + powmod(i, i, 7)) % 7;
    }
    int T; scanf("%d", &T);
    while (T--) {
        long long N; scanf("%lld", &N);
        printf("%s\n", day[sum[N % 294]]);
    }
    return 0;
}

複雜度

  • 預計算:O(294 log N) ≈ 微秒級
  • 查詢:O(1)
  • 空間:O(294)

數學補充

週期 294 = 7 × 42。因 a^b mod 7 依賴 a mod 7 和 b mod 6(對 a≢0)。i mod 7 週期 7,i mod 6 週期 6,合成週期 42。但 i≡0 (mod 7) 時 i^i ≡ 0,需額外考慮。實際最小週期為 294 = 7 × 42。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved