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

传送门

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

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

思路:
显然最后所有选出的数都为\(xa+yb\)的形式。
我们根据贝祖定理,会发现\(xa+yb\)有整数解时,其必然为\(gcd(a,b)\)的倍数,即\(xa+yb=t\cdot 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" << '\n';
        } else {
            cout << "No" << '\n';
        }
    } else {
        if (a & 1 || b & 1) {
            if (n & 1) {
                cout << "Yes" << '\n';
            } else cout << "No" << '\n';
        } else {
            int t = n / 2;
            if (t & 1) {
                cout << "Yes" << '\n';
            } else {
                cout << "No" << '\n';
            }
        }
    }
}
 
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 << '\n';   
    } else {
        cout << fixed << setprecision(1) << res << '\n';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    run();
    return 0;
}

C.张老师的旅行

题意:
数轴上给定\(n,n\leq 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 << '\n';
}

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" << '\n';
                        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" << '\n';
                        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" << '\n';
                        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" << '\n';
                        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" << '\n';
}

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 << '\n';
}

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 << '\n';
}

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次操作以后这叠牌自顶向下的编号情况,你能告诉他吗?

\(n\leq 10^6,k\leq 10^{18}\)

思路:
我们首先来考虑\(k<n\)的情况,我们可以用一个链表来模拟,但是复杂度较高,我们可以观察一下规律:如果我们在\(1,3,5,...\)依次放上\(1,2,3,...\),空出\(2,4,6,...\)
那么我们会发现第\(i\)次操作会放在\(2\cdot (i+1)\)个位置,也就是每次放的位置都是递增的。我们就这样模拟的话时间复杂度为\(O(n)\)的。
那更大的情况呢?
这里我们可以直接通过倍增置换来解决。假设我们已经经过了\(n-1\)次置换,置换的排列为\(p[i]\),即\(i\rightarrow 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] << " \n"[i == n];
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

J.斐波那契和

题意:
\(\displaystyle\sum_{i=1}^ni^kFib(i),n\leq 10^{18},k\leq 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 << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}
posted @ 2020-05-12 12:56  heyuhhh  阅读(245)  评论(0编辑  收藏  举报