【第10题】同余定理相关:ABC179E - Sequence Sum

题目:ABC179E - Sequence Sum

题目原文请移步下面的链接

  • https://www.luogu.com.cn/problem/AT_abc179_e
    • 参考题解:https://www.luogu.com.cn/problem/solution/AT_abc179_e
  • 标签:OIatcoder数学

题解

思路
  • 前置知识:(a * b) mod m = [ (a mod m) * (b mod m) ] mod m
  • 首先n的数据量相当大,又是做乘方运算,直接暴力模拟是不现实的
  • 所以我们可以通过前置知识中的定理去找它余数的循环节,然后通过循环节的和以及n去推导最终答案
代码
#include <bits/stdc++.h>

using namespace std;
#define endl '\n';
typedef long long LL;

void best_coder() {
    LL n, m, x;
    scanf("%lld%lld%lld", &n, &x, &m);
    vector<int> cnt(m + 5);
    vector<LL> solve (m + 5);
    int c = 1;
    LL l, r;
    LL i;
    for (i = x ; ; ++c) {
        if (cnt[i] == 0) {
            cnt[i] = c;
        } else {
            l = cnt[i];
            r = c - 1;
            break;
        }
        ans[c] = solve[c - 1] + i;
        i = (i * i) % m;
    }
    LL len = r - l + 1;
    LL sum = solve[min(n, l - 1)];
    n = max(0ll, n - l + 1);
    if (n > 0) {
        sum += (ans[r] - ans[l - 1]) * (n / len) + (solve[n % len + l - 1] - ans[l - 1]);
    }
    printf("%lld", sum);
}

int main() {
    // 提升cin、cout效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    // 小码匠
    best_coder();

    // 返回
    return 0;
}
代码学习
#include <bits/stdc++.h>
using namespace std;
const int LOG = 35;
int main(){
  long long N;
  int X, M;
  cin >> N >> X >> M;
  vector<vector<int>> next(35, vector<int>(M));
  for (int i = 0; i < M; i++){
    next[0][i] = (long long) i * i % M;
  }
  for (int i = 1; i < LOG; i++){
    for (int j = 0; j < M; j++){
      next[i][j] = next[i - 1][next[i - 1][j]];
    }
  }
  vector<vector<long long>> sum(35, vector<long long>(M));
  for (int i = 0; i < M; i++){
    sum[0][i] = i;
  }
  for (int i = 1; i < LOG; i++){
    for (int j = 0; j < M; j++){
      sum[i][j] = sum[i - 1][j] + sum[i - 1][next[i - 1][j]];
    }
  }
  long long solve = 0;
  for (int i = 0; i < LOG; i++){
    if (N >> i & 1){
      solve += sum[i][X];
      X = next[i][X];
    }
  }
  cout << solve << endl; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码匠和老码农

喜欢作者

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值