codeforces 497E Subsequences Return

codeforces 497E Subsequences Return

想法

做完这题,学了一些东西。

1、求一个串不同子序列个数的两种方法。解一 解二

2、这道题 \(n\) 很大,很容易想到矩阵加速,但是之前遇到的矩阵的题目,矩阵都是相同的,这题的矩阵虽然不同,但是至多 \(k\) 个,并且出现规律与 \(0\) ~ \(n-1\) 的 \(k\) 进制形态有关。题解中基于这点进行的优化和 \(dp\) 的思想又很像。

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(x) (int)x.size()
#define de(x) cout<< #x<<" = "<<x<<endl
#define dd(x) cout<< #x<<" = "<<x<<" "
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int MOD=1e9+7, N=33;

ll n;
int k;
vi dig;

inline void upd(ll &a, ll b) {
    a+=b;
    if(a>=MOD) a-=MOD;
}

struct M {
    ll a[N][N];
    M() {memset(a,0,sizeof(a));}
    void Set() {rep(i,0,k+1) a[i][i]=1;}
    M operator * (const M &c) const {
        M res;
        rep(i,0,k+1) rep(j,0,k+1) rep(_,0,k+1) upd(res.a[i][j], a[i][_]*c.a[_][j]%MOD);
        return res;
    }
}A[N<<1][N], S[N<<1][N], P[N<<1][N], ans;

int main() {
    scanf("%lld%d",&n,&k);
    rep(i,0,k) {
        A[0][i].Set();
        rep(j,0,k+1) A[0][i].a[i][j]=1;
    }
    ll len=k;
    for(int i=1;len<=n;++i, len*=k) {
        S[i-1][k-1]=A[i-1][k-1];
        for(int j=k-2; ~j; --j) S[i-1][j]=A[i-1][j]*S[i-1][j+1];
        P[i-1][0]=A[i-1][0];
        rep(j,1,k) P[i-1][j]=P[i-1][j-1]*A[i-1][j];
        A[i][0]=S[i-1][0];
        rep(j,1,k) A[i][j]=S[i-1][j]*P[i-1][j-1];
    }
    while(n) {
        dig.pb(n%k);
        n/=k;
    }
    int s=0;
    ans.Set();
    for(int i=sz(dig)-1;~i;--i) {
        rep(j,0,dig[i]) {
            ans=ans*A[i][(j+s)%k];
        }
        s=(s+dig[i])%k;
    }
    ll res=1;
    rep(i,0,k) upd(res, ans.a[i][k]);
    printf("%lld\n",res);
    return 0;
}

原文地址:https://www.cnblogs.com/wuyuanyuan/p/8848343.html

时间: 2024-08-02 03:47:36

codeforces 497E Subsequences Return的相关文章

Codeforces 597C. Subsequences (树状数组+dp)

题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长度为j的上升子序列个数,但是dp数组是在树状数组的update函数中进行更新. update(i, val, j)函数表示在i的位置加上val,更新dp[i][j]. sum(i, j)就是求出末尾数字小于等于i 且长度为j的子序列有多少个. 1 //#pragma comment(linker,

codeforces 597C - Subsequences

枚举子序列的末尾,递推. 方案数:f[i = 以i结尾][k =子序列长度] = sum(f[j][k-1]),j < i. 转移就建立k个BIT. #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5+5, K = 10; ll C[K][N]; ll sum(ll C[],int x) { ll re = 0; while(x > 0){ re += C[x];

CodeForces - 844C Sorting by Subsequences (排序+思维)

You are given a sequence a1,?a2,?...,?an consisting of different integers. It is required to split this sequence into the maximum number of subsequences such that after sorting integers in each of them in increasing order, the total sequence also wil

Codeforces Round #361 (Div. 2) D. Friends and Subsequences RMQ+二分

题目链接 http://codeforces.com/problemset/problem/689/D 代码 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 using namespace std; 5 6 const int maxn = 200000 + 10; 7 int n, a[maxn], b[maxn]; 8 int d_min[maxn][30]; 9 int d_max[m

codeforces 597C C. Subsequences(dp+树状数组)

题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output For the given sequence with n different elements find the number of increasing subsequences with k + 1 elements. It is

Codeforces 1132G Greedy Subsequences 线段树

Greedy Subsequences 我们先找到每个点的右边第一个比它大的, 然后从大的往它建边, 然后可以发现这是一棵树. 我们令d[ i ] 为 i 号点往上走最多能走几步, 我们能用线段树维护d 的值. 我们加入点 i 的时候, 我们把它的值设为 d[ fa ] + 1, 我们删除 i 的时候, 把 i 这棵子树中的d 都减 1, 每次询问最大值就好啦. #include<bits/stdc++.h> #define LL long long #define LD long doubl

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) D2. Optimal Subsequences (Hard Version) 数据结构 贪心

D2. Optimal Subsequences (Hard Version) This is the harder version of the problem. In this version, 1≤n,m≤2?105. You can hack this problem if you locked it. But you can hack the previous problem only if you locked both problems. You are given a seque

Codeforces 246E Blood Cousins Return(Dsu On the Tree)

题目链接 Blood Cousins Return 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i) 6 7 const int N = 200010; 8 9 string s[N]; 10 int ans[N], sz[N], h[N]; 11 bool skip[N]; 12 vector <int> v[N

Codeforces Round #361 (Div. 2) D.Friends and Subsequences (multiset + 尺取法)

D. Friends and Subsequences Mike and !Mike are old childhood rivals, they are opposite in everything they do, except programming. Today they have a problem they cannot solve on their own, but together (with you) — who knows? Every one of them has an