传送门

只会爆搜系列

  • 关于「本质不同的子序列个数」:限定长度无限制(就是这题)

    无限制的柿子是(令 \(dp[i]\) 为以 \(i\) 为结尾的不同子序列个数) \(dp[i] = \sum dp[j]+1\),代表在所有子序列末尾后面接上这个字母,且它自身也是一个子序列

然后这题还可以填上 \(m\) 个数,并要求最大化方案数

有个我没想到的贪心,每次填方案数最少的那个字母

因为根据上面的转移,无论这一次选哪个字母,它们的dp值都是一样的

于是发现我们填的数其实是 \(k\) 的一个排列

然后 \(m\) 很大而 \(k\) 只有 \(100\),考虑矩阵快速幂

每 \(k\) 次下来整体的转移是固定的,可以建出系数矩阵

剩下不足 \(k\) 的地方暴力处理就好了

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f
#define N 1000010
#define ll long long
#define ld long double
#define ull unsigned long long
#define fir first
#define sec second
#define make make_pair
#define reg register int
//#define int long long char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline ll read() {
ll ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
} int n, k; ll m;
int a[N];
const ll mod=1e9+7;
int mod2=1e9+7;
//inline void md(ll& a, ll b) {a+=b; a=a>=mod?a-mod:a;}
inline void md(ll& a, ll b) {a+=b; a=a>=mod?a-mod:a;}
inline void md2(int& a, int b) {a+=b; a=a>=mod2?a-mod2:a;}
const ull base=131;
unordered_map<ull, bool> mp, mp2; namespace task1{
void dfs(int u, ull dat) {
dat=dat*base+a[u];
mp[dat]=1;
for (int i=u+1; i<=n; ++i) {
dfs(i, dat);
}
}
void solve() {
for (int i=1; i<=n; ++i) dfs(i, 0);
cout<<mp.size()%mod<<endl;
exit(0);
}
} namespace task2{
ull sta[N]; int top; unsigned ans;
void dfs(int u, unordered_map<ull, bool> tmp) {
//cout<<"dfs "<<u<<endl;
if (u>m) {ans=max(ans, tmp.size()); return ;}
top=0; ull tem;
for (int j=1; j<=k; ++j) {
//cout<<"j: "<<j<<endl;
unordered_map<ull, bool> tp2=tmp;
for (auto it:tmp) {
tem=it.fir;
tp2[tem*base+j]=1;
}
tp2[j]=1;
dfs(u+1, tp2);
}
}
void solve() {
for (int i=1; i<=n; ++i) task1::dfs(i, 0);
dfs(1, mp);
cout<<ans<<endl;
}
} namespace task3{
ll dp[110]; ld dp2[110];
int sta[110], top;
void solve() {
ll sum; ld sum2;
for (int i=1; i<=n; ++i) {
sum=0; sum2=0;
for (int j=1; j<=k; ++j)
md(sum, dp[j]), sum2+=1.0*dp[j];
dp[a[i]]=sum, dp2[a[i]]=sum2+1.0;
md(dp[a[i]], 1);
}
for (int i=1,pos=0; i<=m; ++i,pos%=k) {
if (top==k) {
sum=0; sum2=0;
for (int j=1; j<=k; ++j)
md(sum, dp[j]), sum2+=dp[j];
dp[sta[pos]]=sum; dp2[sta[pos]]=sum2+1;
md(dp[sta[pos++]], 1);
}
else {
//ll minn=INF;
ld minn=1e1000l; int mini=0; sum=0; sum2=0;
for (int j=1; j<=k; ++j) {
if (dp2[j]<minn) minn=dp2[j], mini=j;
md(sum, dp[j]), sum2+=dp2[j];
}
dp[mini]=sum; dp2[mini]+=sum2;
md(dp[mini], 1);
sta[top++]=mini;
}
}
sum=0;
for (int i=1; i<=k; ++i) md(sum, dp[i]);
printf("%lld\n", sum);
exit(0);
}
} namespace task{
int dp[110], sum3[110], vec[110];
queue<int> q;
struct matrix{
int a[110][110];
int n, m;
matrix() {memset(a, 0, sizeof(a));}
matrix(int x, int y):n(x),m(y) {memset(a, 0, sizeof(a));}
void resize(int a, int b) {n=a; m=b;}
void put() {for (int i=1; i<=n; ++i) {for (int j=1; j<=m; ++j) cout<<a[i][j]<<' '; cout<<endl;}}
inline int* operator [] (int t) {return a[t];}
inline matrix operator * (matrix& b) {
matrix ans(n, b.m);
for (reg i=1; i<=n; ++i)
for (reg k=1; k<=m; ++k)
for (reg j=1; j<=b.m; ++j)
md2(ans[i][j], 1ll*a[i][k]*b[k][j]%mod);
return ans;
}
}mat, tem;
matrix qpow(matrix &a, ll b) {
matrix ans=a; --b;
while (b) {
if (b&1) ans=ans*a;
a=a*a; b>>=1;
}
return ans;
}
void solve() {
int sum=0, lst=0;
mat.resize(1, k+1); tem.resize(k+1, k+1);
int u;
for (reg i=1; i<=n; ++i) {
//cout<<"u: "<<u.fir<<' '<<u.sec<<endl;
lst=dp[a[i]];
dp[a[i]]=sum;
md2(dp[a[i]], 1);
sum=(sum-lst+sum+1)%mod2;
sum=(sum+mod)%mod2;
vec[a[i]]=i;
}
//for (int i=1; i<=k; ++i) md(sum, dp[i]);
pair<int, int> s[110];
for (reg i=1; i<=k; ++i) s[i]=make(vec[i], i);
sort(s+1, s+k+1);
for (reg i=1; i<=k; ++i) q.push(s[i].sec);
int lim=m%k;
//cout<<"lim: "<<lim<<endl;
for (reg i=1,mini; i<=lim; ++i) {
u=q.front(); q.pop();
lst=dp[u];
dp[u]=sum;
md2(dp[u], 1);
sum=(sum-lst+sum+1)%mod2;
sum=(sum+mod2)%mod2;
q.push(u);
}
for (reg i=1; i<=k+1; ++i) tem[i][i]=1;
//cout<<"---tem(ini t)---"<<endl;
//tem.put(); cout<<endl;
for (reg i=1; i<=k; ++i) mat[1][i]=dp[i]; mat[1][k+1]=1;
for (reg i=1; i<=k; ++i) {
u=q.front(); q.pop();
memset(sum3, 0, sizeof(sum3));
for (reg j=1; j<=k; ++j)
for (reg h=1; h<=k+1; ++h)
md2(sum3[h], tem[j][h]);
memcpy(tem[u], sum3, sizeof(sum3));
++tem[u][k+1];
q.push(u);
}
for (reg i=1; i<=k+1; ++i)
for (reg j=i+1; j<=k+1; ++j)
swap(tem[i][j], tem[j][i]);
#if 0
cout<<"---mat---"<<endl;
mat.put(); cout<<endl;
cout<<"---tem---"<<endl;
tem.put(); cout<<endl;
cout<<"qpow: "<<m/k<<endl;
#endif
tem=qpow(tem, m/k);
mat=mat*tem;
ll ans=0;
//cout<<"---ans---"<<endl;
//for (int i=1; i<=k; ++i) cout<<mat[1][i]<<' '; cout<<endl;
for (reg i=1; i<=k; ++i) md(ans, mat[1][i]);
printf("%lld\n", ans);
exit(0);
}
} signed main()
{
n=read(); m=read(); k=read();
for (int i=1; i<=n; ++i) a[i]=read();
if (!m) task3::solve();
else task::solve();
//task3::solve();
//task::solve(); return 0;
}

题解 Sequence的更多相关文章

  1. 【CF486E】LIS of Sequence题解

    [CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 ...

  2. 题解——CodeForces 438D The Child and Sequence

    题面 D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input ...

  3. HDU1560 DNA sequence(IDA*)题解

    DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  4. 【题解】Cut the Sequence(贪心区间覆盖)

    [题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...

  5. Ural 1248 Sequence Sum 题解

    目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...

  6. 题解【Codeforces438D】The Child and Sequence

    题目描述 At the children's day, the child came to Picks's house, and messed his house up. Picks was angr ...

  7. CF3D Least Cost Bracket Sequence 题解

    题目 This is yet another problem on regular bracket sequences. A bracket sequence is called regular, i ...

  8. Numerical Sequence (Hard vision) 题解

    The only difference between the easy and the hard versions is the maximum value of \(k\). You are gi ...

  9. [LeetCode]题解(python):060-Permutation Sequence

    题目来源 https://leetcode.com/problems/permutation-sequence/ The set [1,2,3,…,n] contains a total of n! ...

随机推荐

  1. Kubernetes-22:kubelet 驱逐策略详解

    为什么要驱逐pod? 在可用计算资源较少时,kubelet为保证节点稳定性,会主动地结束一个或多个pod以回收短缺地资源,这在处理内存和磁盘这种不可压缩资源时,驱逐pod回收资源的策略,显得尤为重要. ...

  2. ffiddler抓取手机(app)https包

    很多同学有看过原文,但是按照原文还是没有设置成功(我就是其中一个)然后查了网上资料,在某些选项上进行增加,填写,配置通过.(和原文略有不同) 安装Fiddler,我们正常的流程在feiddler中设置 ...

  3. CTF-wtc_rsa_bbq-writeup

    wtc_rsa_bbq 题目信息: 附件: cry200 解题思路: 1.观察cry200文件,发现该文件是一个二进制文件,用二进制模式查看,发现开头为50 4B 03 04,判断该文件是一个zip文 ...

  4. JAVA程序系统测试感受

    JAVA课程才刚刚开始,就仿佛经历了一场劫难,让我们叫苦连天,苦不堪言.暑假学的一些皮毛java知识,到了真正需要写一个相对完整的软件系统,就如同废材一样,实在是用不上来.我看着小民哥布置的考试内容, ...

  5. 【转载】Java学习笔记

    转载:博主主页 博主的其他笔记汇总 : 学习数据结构与算法,学习笔记会持续更新: <恋上数据结构与算法> 学习Java虚拟机,学习笔记会持续更新: <Java虚拟机> 学习Ja ...

  6. Requests方法 -- 参数关联

    一.删除草稿箱1.参数这篇https://www.cnblogs.com/Teachertao/p/11144726.html 2.删除刚才保存的草稿 3.用 fiddler 抓包,抓到删除帖子的请求 ...

  7. PAT乙级:1015 德才论 (25分)

    1015 德才论 (25分) 宋代史学家司马光在<资治通鉴>中有一段著名的"德才论":"是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人 ...

  8. npm命令,nrm命令,n命令, nvm命令

    npm命令 npm/yarn config set registry https://registry.npm.taobao.org 设置淘宝镜像npm/yarn config get registr ...

  9. list实现从大到小排序

    public static void main(String[] args) { List<Integer> list=new ArrayList<Integer>(); // ...

  10. Python中strip()、lstrip()、rstrip()函数的用法

    Python中使用函数strip().lstrip().rstrip()来剔除字符串前后的特定字符 函数语法为:str.strip(chars) 返回值是一个新的字符串,不更改源字符串 其中,参数ch ...