传送门

只会爆搜系列

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

    无限制的柿子是(令 \(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. 使用VS远程调试其他电脑上安装的软件

    今天在用户的一台机器上遇到了很奇怪的问题.一个按钮点击时概率性的第一次点击无反馈. 因为是概率性的,概率又很低,而当初在设计Log时又设计的是必须重启软件才会生效log开关: 所以这里使用当时rele ...

  2. Pytest学习笔记12-配置文件pytest.ini

    前言 pytest配置文件可以改变pytest的运行方式,它是一个固定的文件pytest.ini文件,读取配置信息,按指定的方式去运行. 常用的配置项 marks 作用:测试用例中添加了自定义标记( ...

  3. echarts堆叠柱状图在最上面的柱子显示总和

    需求 柱子需设置barMinHeight 在堆叠柱状图的最上面显示当前堆叠的总和 直接上代码吧 需要注意:设置barMinHeight时为了让0不显示,只能将0设置为null; 设置为null的柱子l ...

  4. 华为交换机5855设置ssh

    配置思路 配置交换机密钥对 #生成RSA密钥对 设置vty登陆用户界面的认证方式为AAA认证 #设置远程认证方式 设置aaa用户信息 #本地用户名和密码 #本地用户服务类型 #本地用户授权等级 设置s ...

  5. Docker以过时,看Containerd怎样一统天下

    Docker作为非常流行的容器技术,之前经常有文章说它被K8S弃用了,取而代之的是另一种容器技术containerd!其实containerd只是从Docker中分离出来的底层容器运行时,使用起来和D ...

  6. C++ 标准模板库(STL)——容器(Containers)的用法及理解

    C++ 标准模板库(STL)中定义了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量(vector).队列(queue).栈(stack).set.map等.这次主要 ...

  7. C语言:强制类型转换

    #include <stdio.h> //强制类型转换 //写法:(类型标识符)变量:(类型标识符)常量:(类型标识符)(表达式):三种格式 main() { float a=7.5f; ...

  8. C语言:打印所有char字符

    #include <stdio.h> int main() { int aa; char bla; for(aa=0;aa<=255;aa++) { if(aa%10==0 and ...

  9. 【模拟】报名签到 luogu-4445

    AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...

  10. 解决跨网段intouch嵌入视频问题

    在自控项目中,一般会将视频网络和自控网络分开,分属于两个不同的逻辑网段,以避免局域网ip不够用的问题.这就造成了一个问题,如何实现在自控网络上位机访问摄像头并嵌入使用?这里其实很简单,因为这两个网络本 ...