• “科大讯飞杯”第十七届同济大学程序设计预选赛暨高校网络友谊赛


    传送门

    A.张老师和菜哭武的游戏

    题意:
    现有数为(1)~(n)的集合,两个人从中选出(a,b,a ot ={b}),然后两个人依次轮流从集合选出一个数(z),满足(z=x+y,z=x-y,x,y)为已选出的两个数。
    问是否第一个人能够获胜。

    思路:
    显然最后所有选出的数都为(xa+yb)的形式。
    我们根据贝祖定理,会发现(xa+yb)有整数解时,其必然为(gcd(a,b))的倍数,即(xa+yb=tcdot gcd(a,b))
    所以就算出(gcd)然后判断一下就行。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 13:33:47
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A>
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 10000 + 5;
     
    bool chk[N];
     
    void run() {
        int n, a, b; cin >> n >> a >> b;
        if (a > b) swap(a, b);
        if (b % a == 0) {
            int t = n / a;
            if (t & 1) {
                cout << "Yes" << '
    ';
            } else {
                cout << "No" << '
    ';
            }
        } else {
            if (a & 1 || b & 1) {
                if (n & 1) {
                    cout << "Yes" << '
    ';
                } else cout << "No" << '
    ';
            } else {
                int t = n / 2;
                if (t & 1) {
                    cout << "Yes" << '
    ';
                } else {
                    cout << "No" << '
    ';
                }
            }
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    B.伤害计算

    随便算一算。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 13:57:43
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 5000 + 5;
    
    char s[N];
    int n;
    const double eps = 1e-6;
    
    void run() {
        cin >> (s + 1);
        n = strlen(s + 1);
        double res = 0;
        for (int i = 1, j; i <= n; i = j) {
            j = i;
            int x = 0, y = 0;
            while (j <= n && s[j] <= '9' && s[j] >= '0') {
                x = x * 10 + s[j] - '0';
                ++j;
            }
            if (j <= n && s[j] == '+') {
                res += x;
                ++j; continue;
            } else if(j > n) {
                res += x;
                continue;
            }
            ++j;
            while (j <= n && s[j] <= '9' && s[j] >= '0') {
                y = y * 10 + s[j] - '0';
                ++j;
            }
            res += 1.0 * x * (y + 1) * y / 2 / y;
        }
        if (fabs(res - round(res)) <= eps) {
            cout << (ll) res << '
    ';   
        } else {
            cout << fixed << setprecision(1) << res << '
    ';
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        run();
        return 0;
    }
    

    C.张老师的旅行

    题意:
    数轴上给定(n,nleq 1000)个点,每个点的位置为(p_i)
    起点位于(x),现在有个人从起点出发,要遍历所有的点,走一单位路程花费一单位时间。问遍历所有点最少花多少时间。

    思路:
    我们容易发现这样一个性质:

    • 每次这个人会遍历完一段区间([l,r])中的点。

    那么这就是一个比较套路的(dp)了,我们直接用(dp_{l,r,0/1})表示遍历完区间([l,r]),当前在区间的左端点/右端点的最短花费。转移向左向右两种情况转移即可。
    其实也就是个最短路问题,赛场上我写了一下dijkstra。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 14:56:58
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e3 + 5;
    
    int n, x;
    int p[N], t[N];
    
    ll dis[N][N];
    struct Dijkstra{
        struct node{
            ll d;
            pii sta;
            bool operator < (const node &A) const {
                return d > A.d;
            }   
        };
        bool vis[N][N];
        void dij(int s) {
            priority_queue <node> q;
            memset(dis, INF, sizeof(dis));
            memset(vis, 0, sizeof(vis));
            dis[s][1] = 0;
            q.push(node{0, MP(s, 1)});
            while(!q.empty()) {
                node cur = q.top(); q.pop();
                ll d = cur.d;
                pii sta = cur.sta;
                int now = sta.fi, had = sta.se;
                if(vis[now][had]) continue;
                vis[now][had] = 1;
                dis[now][had] = d;
                if (now <= x) {
                    if (now + had <= n && p[now + had] - p[now] + d <= t[now + had]) {
                        q.push(node{p[now + had] - p[now] + d, MP(now + had, had + 1)});
                    } 
                    if (now > 1 && d + p[now] - p[now - 1] <= t[now - 1]) {
                        q.push(node{d + p[now] - p[now - 1], MP(now - 1, had + 1)});
                    }
                } else {
                    if (now - had >= 1 && p[now] - p[now - had] + d <= t[now - had]) {
                        q.push(node{p[now] - p[now - had] + d, MP(now - had, had + 1)});
                    } 
                    if (now < n && d + p[now + 1] - p[now] <= t[now + 1]) {
                        q.push(node{d + p[now + 1] - p[now], MP(now + 1, had + 1)});
                    }               
                }
            }
        }
    }solver;
    
    void run() {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> p[i];
        }
        for (int i = 1; i <= n; i++) {
            cin >> t[i];
            if (t[i] == 0) x = i;
        }
        solver.dij(x);
        ll ans = min(dis[1][n], dis[n][n]);
        if (ans == dis[0][0]) ans = -1;
        cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    D.车辆调度

    由于数据范围很小,直接(dfs)枚举所有的可能性就可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 14:34:55
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 10 + 1;
    
    int w, h, k;
    char s[N][N];
    
    void dfs(int cur, char s[][N]) {
        if (cur == k) return;   
        for (int i = 1; i <= w; i++) {
            for (int j = 1; j <= h; j++) if (s[i][j] == 'R') {
                for (int k = j; k >= 1; k--) {
                    if (k - 1 < 1 || s[i][k - 1] == 'X' || s[i][k - 1] == 'R') {
                        if (s[i][k] == 'D') {
                            cout << "YES" << '
    ';
                            exit(0);   
                        }
                        swap(s[i][k], s[i][j]);
                        dfs(cur + 1, s);
                        swap(s[i][k], s[i][j]);
                        break;
                    }
                }
                for (int k = j; k <= h; k++) {
                    if (k + 1 > h || s[i][k + 1] == 'X' || s[i][k + 1] == 'R') {
                        if (s[i][k] == 'D') {
                            cout << "YES" << '
    ';
                            exit(0);   
                        }
                        swap(s[i][k], s[i][j]);
                        dfs(cur + 1, s);
                        swap(s[i][k], s[i][j]);
                        break;
                    }   
                }
                for (int k = i; k >= 1; k--) {
                     if (k - 1 < 1 || s[k - 1][j] == 'X' || s[k - 1][j] == 'R') {
                        if (s[k][j] == 'D') {
                            cout << "YES" << '
    ';
                            exit(0);   
                        }
                        swap(s[k][j], s[i][j]);
                        dfs(cur + 1, s);
                        swap(s[k][j], s[i][j]);
                        break;
                    }                  
                }
                for (int k = i; k <= w; k++) {
                     if (k + 1 > w || s[k + 1][j] == 'X' || s[k + 1][j] == 'R') {
                        if (s[k][j] == 'D') {
                            cout << "YES" << '
    ';
                            exit(0);   
                        }
                        swap(s[k][j], s[i][j]);
                        dfs(cur + 1, s);
                        swap(s[k][j], s[i][j]);
                        break;
                    }                  
                }
            }   
        }
    }
    
    void run() {
        cin >> w >> h >> k;
        swap(w, h);
        for (int i = 1; i <= w; i++) {
            cin >> (s[i] + 1);
        }
        dfs(0, s);
        cout << "NO" << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    E.弦

    题意:

    给定一个圆,圆上有2N个互不重叠的点。每次操作随机选择两个先前未选择过的点连一条弦,共连成N条弦,求所有弦不交的概率。

    思路:
    我们直接用合法情况除以总情况即可。
    合法情况就是一个卡特兰数,为什么呢。我们用(f(i))表示(i)对点的情况数,那么转移就是(displaystyle f(i)=sum_{k=0}^{i-1}f(k)cdot f(i-1-k))。这就是卡特兰数的递推式。
    总的情况组合数算一算就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 16:20:55
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e7 + 5, MOD = 1e9 + 7;
    
    int qpow(ll a, ll b) {
        ll res = 1;
        while (b) {
            if (b & 1) res = res * a % MOD;
            a = a * a % MOD;
            b >>= 1; 
        }
        return res;   
    }
    
    void run() {
        int n; cin >> n;
        int fac = 1;
        for (int i = 1; i <= n + 1; i++) fac = 1ll * fac * i % MOD;
        int ans = 1ll * qpow(2, n) * qpow(fac, MOD - 2) % MOD;
        cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    F.排列计算

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 13:12:25
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 2e5 + 5;
    
    int n, m;
    int a[N];
    
    void run() {
        cin >> n >> m;
        for (int i = 1; i <= m; i++) {
            int l, r; cin >> l >> r;
            ++a[l], --a[r + 1];
        }
        for (int i = 1; i <= n; i++) {
            a[i] += a[i - 1];
        }
        sort(a + 1, a + n + 1);
        ll ans = 0;
        for (int i = n; i >= 1; i--) {
            ans += 1ll * i * a[i];
        }
        cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    I.纸牌

    题意:

    桌上有一叠共N张牌,从顶向下标号为1~N。张老师打算对这一叠牌做k次操作,其中第i次操作会将牌堆顶的牌放在牌堆中的某个位置,从而满足这张牌成为自顶向下第(i - 1) % (N - 1) + 2张牌,其中%表示取模操作。张老师想知道k次操作以后这叠牌自顶向下的编号情况,你能告诉他吗?

    (nleq 10^6,kleq 10^{18})

    思路:
    我们首先来考虑(k<n)的情况,我们可以用一个链表来模拟,但是复杂度较高,我们可以观察一下规律:如果我们在(1,3,5,...)依次放上(1,2,3,...),空出(2,4,6,...)
    那么我们会发现第(i)次操作会放在(2cdot (i+1))个位置,也就是每次放的位置都是递增的。我们就这样模拟的话时间复杂度为(O(n))的。
    那更大的情况呢?
    这里我们可以直接通过倍增置换来解决。假设我们已经经过了(n-1)次置换,置换的排列为(p[i]),即(i ightarrow p[i])。那么我们可以直接通过(p[p[i]])求出(2n-2)次置换。那么这里我们可以类似于快速幂那样进行倍增。
    最后剩余我们可以直接类似于上面那样进行模拟。
    总时间复杂度(O(nlog(frac{k}{n-1})))
    细节见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/11 10:42:59
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e6 + 5;
    
    int n;
    ll k;
    int base[N], a[N];
    
    int tmp[N << 1], res[N];
    
    void Iter(int x, int* a) {
        for (int i = 1;  i<= n; i++) {
            tmp[2 * i - 1] = a[i];
            tmp[2 * i] = 0;
        }
        int p = 1;
        for (int i = 1; i <= x; i++) {
            while (tmp[p] == 0) ++p;
            swap(tmp[p], tmp[(i + 1) * 2]);
        }
        int t = 0;
        for (int i = 1; i <= 2 * n; i++) {
            if (tmp[i] > 0) {
                a[++t] = tmp[i];
            }
        }
    }
    
    void mul(int* a, int* b) {
        for (int i = 1; i <= n; i++) {
            res[i] = a[b[i]];
        }
        for (int i = 1; i <= n; i++) {
            a[i] = res[i];
        }
    }
    
    void run() {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            base[i] = a[i] = i;
        }
        ll t = k / (n - 1), r = k % (n - 1);
        Iter(n - 1, base);
        while (t) {
            if (t & 1) mul(a, base);
            mul(base, base);
            t >>= 1;
        }
        Iter(r, a);
        for (int i = 1; i <= n; i++) {
            cout << a[i] << " 
    "[i == n];
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    J.斐波那契和

    题意:
    (displaystylesum_{i=1}^ni^kFib(i),nleq 10^{18},kleq 100)

    思路:
    就算出前面若干项(好像400项就行),然后扔进BM里面结果就出来了。
    具体为啥我也不是很清楚。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/5/10 14:16:41
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e6 + 5, MOD = 998244353;
    
    int fib[N];
    void init() {
        fib[1] = fib[2] = 1;
        for (int i = 3; i < N; i++) {
            fib[i] = (fib[i - 1] + fib[i - 2]) % MOD;
        }
    }
    
    ll n, k;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define SZ(x) ((int)(x).size())
    
    typedef vector<int> VI;
    typedef long long ll;
    
    ll powMOD(ll a, ll b) {
        ll ans = 1;
        for (; b; b >>= 1, a = a * a%MOD)if (b & 1)ans = ans * a%MOD;
        return ans;
    }
    namespace linear_seq {
        ll res[N], base[N], _c[N], _md[N];
    
        vector<int> Md;
        void mul(ll *a, ll *b, int k) {
            rep(i, 0, k + k) _c[i] = 0;
            rep(i, 0, k) if (a[i]) rep(j, 0, k) _c[i + j] = (_c[i + j] + a[i] * b[j]) % MOD;
            for (int i = k + k - 1; i >= k; i--) if (_c[i])
                rep(j, 0, SZ(Md)) _c[i - k + Md[j]] = (_c[i - k + Md[j]] - _c[i] * _md[Md[j]]) % MOD;
            rep(i, 0, k) a[i] = _c[i];
        }
        int solve(ll n, VI a, VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
            ll ans = 0, pnt = 0;
            int k = SZ(a);
            assert(SZ(a) == SZ(b));
            rep(i, 0, k) _md[k - 1 - i] = -a[i]; _md[k] = 1;
            Md.clear();
            rep(i, 0, k) if (_md[i] != 0) Md.push_back(i);
            rep(i, 0, k) res[i] = base[i] = 0;
            res[0] = 1;
            while ((1ll << pnt) <= n) pnt++;
            for (int p = pnt; p >= 0; p--) {
                mul(res, res, k);
                if ((n >> p) & 1) {
                    for (int i = k - 1; i >= 0; i--) res[i + 1] = res[i]; res[0] = 0;
                    rep(j, 0, SZ(Md)) res[Md[j]] = (res[Md[j]] - res[k] * _md[Md[j]]) % MOD;
                }
            }
            rep(i, 0, k) ans = (ans + res[i] * b[i]) % MOD;
            if (ans < 0) ans += MOD;
            return ans;
        }
        VI BM(VI s) {
            VI C(1, 1), B(1, 1);
            int L = 0, m = 1, b = 1;
            rep(n, 0, SZ(s)) {
                ll d = 0;
                rep(i, 0, L + 1) d = (d + (ll)C[i] * s[n - i]) % MOD;
                if (d == 0) ++m;
                else if (2 * L <= n) {
                    VI T = C;
                    ll c = MOD - d * powMOD(b, MOD - 2) % MOD;
                    while (SZ(C) < SZ(B) + m) C.pb(0);
                    rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % MOD;
                    L = n + 1 - L; B = T; b = d; m = 1;
                }
                else {
                    ll c = MOD - d * powMOD(b, MOD - 2) % MOD;
                    while (SZ(C) < SZ(B) + m) C.pb(0);
                    rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % MOD;
                    ++m;
                }
            }
            return C;
        }
        int gao(VI& a, ll n) {
            VI c = BM(a);
            c.erase(c.begin());
            rep(i, 0, SZ(c)) c[i] = (MOD - c[i]) % MOD;
            return solve(n, c, VI(a.begin(), a.begin() + SZ(c)));
        }
    };
    
    void run() {
        init();
        cin >> n >> k;
        vector <int> f(N);
        f[0] = 0;
        for (int i = 1; i < N; i++) {
            f[i] = (f[i - 1] + 1ll * powMOD(i, k) * fib[i] % MOD) % MOD;
        }
        int res = linear_seq::gao(f, n);
        cout << res << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    redis-cluster
    Mycat-主从结构的准备
    Mycat-多实例的搭建
    MSC添加shard节点
    MongoDB -MSC集群的部署
    MySQL知识-redis实例
    MySQL知识-MySQL不同版本多实例
    #Linux学习# 用户和用户组管理
    #Linux学习# 软件包管理
    #Linux学习# 文本编辑器vim
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12875511.html
Copyright © 2020-2023  润新知