首页 > 其他分享 >Atcoder357D题解(求解等比数列求和公式的推导)

Atcoder357D题解(求解等比数列求和公式的推导)

时间:2024-06-10 21:46:26浏览次数:22  
标签:10 等比数列 int 题解 ll Atcoder357D define sum mod

解题思路

  1. 设连接之后的N等于N last,w = 10 ^ (N在10进制下的长度,例如N = 5,那么w = 10)
  2. N last = N + N * w + N * (w ^ 2) + N * (w ^ 3) + ..... + N * (w ^ n)
  3. 举个例子N= 5,因为510进制的长度是1,所以w = 10,那么N last = 5 + 5 * 10(w) ^ 1 + 5 * 10(w) ^ 2 + 5 * 10(w) ^ 3 + 5 * 10(w) ^ 4 + 5 * 10(w) ^ 5
  4. 其实就是N last每次拼接的数学表示
  5. 那么化简一下上面的式子
  6. N last = N + N * w + N * (w ^ 2) + N * (w ^ 3) + ..... + N * (w ^ n)

      = N * (w ^ 0 + w ^ 1 + w ^ 2 + w ^3 + .... + w ^ (n - 1))

如果不会乘法逆元的话就可以使用分治法求解等比数列的求和公式

设以公比为q, 一直到n的求和为sum(q, n) = q ^0 + q ^ 1 + q ^ 2 + ..... + q^n

那么当n是奇数时,我们可以化简为 

sum(q, n) = q ^ 0 + q ^ 1 + q ^ ((n - 1) / 2) + q ^ ((n + 1) / 2) + q ^ (n + 3) / 2 + ........ +  q ^ n

提出一个对于后半部分提出一个q ^ ((n + 1) / 2)原式等于

= q ^ 0 + q ^ 1 + q ^ ((n - 1) / 2) + q ^ ((n + 1) / 2) * (q ^ 0 + q ^ 1 + q ^ ((n - 1) / 2))

= (1 + q ^ ((n + 1) / 2)) * (q ^ 0 + q ^ 1 + q ^ ((n - 1) / 2))

那么不就是(1 + q ^ ((n + 1) / 2)) * sum(q, (n - 1) / 2)吗,时间复杂度O(logN)

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define sc scanf
#define pr printf
#define endl '\n'
#define sz(x) int((x).size())
#define all(x) x.begin(), x.end()
#define pb(x) push_back(x)

using namespace std;
using ll = long long;
typedef pair<ll, ll> pll;


const int INF = 0x3f3f3f3f;
const int N = 2 * 1e5 + 10;
const int mod = 998244353;

int d[4][2] = {
    {-1, 0}, {1, 0}, {0, -1}, {0, 1}
};

int t;
ll n;

ll qpow(ll a, ll b, ll p) {
    ll ans = 1;

    while (b) {
        if (b & 1) {
            ans = ans * a % p;
        }

        a = a * a % p;
        b >>= 1;
    }

    return ans % p;
}

ll sum(ll p, ll k) {
    if (k == 0) {
        return 1;
    }

    if (k % 2 == 0) {
        return (qpow(p, k, mod) + sum(p, k - 1) + mod) % mod;
    }

    return (1 + qpow(p, (k + 1) / 2, mod)) % mod * sum(p, (k - 1) / 2) % mod;
}

void solve() {
    cin >> n;
   
    ll tmp = n;
    int cnt = 0;

    while (tmp) {
        tmp /= 10;
        cnt ++;
    }

    ll w = qpow(10, cnt, mod);//求出公比
    ll ans = n  % mod * sum(w, n - 1) % mod;

    cout << ans << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    t = 1;

    while (t--) {
        solve();
    }

    return 0;
}

 

标签:10,等比数列,int,题解,ll,Atcoder357D,define,sum,mod
From: https://www.cnblogs.com/lwj1239/p/18241066

相关文章

  • Luogu P1784 数独 [ 模板 ] / P1074 靶形数独 题解 [ 蓝 ] [ 深搜 ] [ 剪枝 ] [ 卡常
    数独模板,靶形数独卡了2h,再也不想写数独了。思路显然是对每个格子进行枚举,类似八皇后的方法去做,朴素方法是由\((1,1)\)到\((9,9)\)遍历过去。优化我们人在做数独时,会优先选择已填格数多的行、列、区域,这样可以保证尝试次数少。同样,这一点在本题中也可以应用,但是有两......
  • [题解]P9432 [NAPC-#1] rStage5 - Hard Conveyors
    P9432[NAPC-#1]rStage5-HardConveyors题意简述给定一个\(N\)个节点的树形结构,其中有\(k\)个关键节点。接下来有\(q\)次询问,每次询问给定\(x,y\),请输出\(x\)到\(y\)至少经过一个关键点的最短路径。解题思路我们发现,这道题相当于让我们从\(x\)到\(y\)的简单路径上,额外扩展......
  • P10572 [JRKSJ R8] +1-1 题解
    样例给了我们一个很好的提示。观察样例中\(1\rightarrow4\)的路径,发现\(4\rightarrow5\)这条边走了两遍,再结合题目描述中不需要保证是简单路径的提示,我们发现:如果路径两侧分别是(\(\rightarrow\)(和)\(\rightarrow\))的话,那么中间不管怎么走都可以通过左右横跳来......
  • LibreOJ #10131. 「一本通 4.4 例 2」暗的连锁 题解 树上差分
    暗的连锁题目描述Dark是一张无向图,图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N−1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。你的任务是把Dark斩为不连通的两部分。一开始Da......
  • [题解]P9433 [NAPC-#1] Stage5 - Conveyors
    P9433[NAPC-#1]Stage5-Conveyors题意简述给定一个\(N\)个节点的树形结构,每条边有边权,树上有\(k\)个关键点。接下来有\(q\)次询问,每次询问给定\(x,y\)两点,请计算从\(x\)开始经过这\(k\)个关键点(可以重复经过)再到\(y\)的最短路程。解题思路我们可以发现,如果\(x\)与\(y\)都......
  • 牛客周赛 Round 46 题解 C++
    目录 A 乐奈吃冰B 素世喝茶C 爱音开灯D 小灯做题E 立希喂猫F 祥子拆团 A 乐奈吃冰#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<set>#include<vector>#include<unordered_map>......
  • 斜率优化DP简单总结&&“土地购买”题解
    今天刚刷完了斜率优化DP,简单从头回顾一下。\[首先,能写出DP方程应该是最重要的,毕竟斜率只是用来优化的\]那么一个DP方程能用斜率优化,具备一种形式:\[f[i]+s1[i]+A[i]*B[j]=f[j]+s2[j]\]其中,f[i]表示所求值,(s1[i]、A[i])与(s2[j]、B[j])分别表示只与i或j有关的一个表达式(可以是只有常......
  • Codeforces Round 837题解(A、B)
    A.HossamandCombinatorics\(|a_i-a_j|\)最大的就是最大值和最小值,注意要开longlong。intn;inta[N];voidsolve(){cin>>n;intmin_v=INF,max_v=0;for(inti=1;i<=n;i++){cin>>a[i];min_v=min(min_v,a[i......
  • CF1970F1 Playing Quidditch (Easy) 题解
    一道大模拟题。这道题可以用一个 map 记录球员及鬼飞球当时的坐标,用一个数组 a 记录是否有人进球,用另一个数组 b 记录每位球员是否有鬼飞球。当球员抓住鬼飞球后,鬼飞球跟着这个球员移动,直到这个球员投球。话不多说,直接上代码。MyCode:#include<bits/stdc++.h>#de......
  • 【题解】 [CSP-J 2019] 纪念品
    题目描述题目大意在\(T\)天内,有\(n\)种纪念品和初始的\(m\)元。可以得到每天每种纪念品的价格。每一天可以以当日价格买卖纪念品。特别的,当天卖出得到的钱可以当天买入,当日买入的纪念品也可以当日卖出。当然可以一直持有。但是,\(T\)天过后,手上不可以持有纪念品。思路......