题解 Sequence
只会爆搜系列
- 关于「本质不同的子序列个数」:限定长度,无限制(就是这题)
无限制的柿子是(令 \(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的更多相关文章
- 【CF486E】LIS of Sequence题解
[CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 ...
- 题解——CodeForces 438D The Child and Sequence
题面 D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input ...
- HDU1560 DNA sequence(IDA*)题解
DNA sequence Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 【题解】Cut the Sequence(贪心区间覆盖)
[题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...
- Ural 1248 Sequence Sum 题解
目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...
- 题解【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 ...
- CF3D Least Cost Bracket Sequence 题解
题目 This is yet another problem on regular bracket sequences. A bracket sequence is called regular, i ...
- Numerical Sequence (Hard vision) 题解
The only difference between the easy and the hard versions is the maximum value of \(k\). You are gi ...
- [LeetCode]题解(python):060-Permutation Sequence
题目来源 https://leetcode.com/problems/permutation-sequence/ The set [1,2,3,…,n] contains a total of n! ...
随机推荐
- 使用VS远程调试其他电脑上安装的软件
今天在用户的一台机器上遇到了很奇怪的问题.一个按钮点击时概率性的第一次点击无反馈. 因为是概率性的,概率又很低,而当初在设计Log时又设计的是必须重启软件才会生效log开关: 所以这里使用当时rele ...
- Pytest学习笔记12-配置文件pytest.ini
前言 pytest配置文件可以改变pytest的运行方式,它是一个固定的文件pytest.ini文件,读取配置信息,按指定的方式去运行. 常用的配置项 marks 作用:测试用例中添加了自定义标记( ...
- echarts堆叠柱状图在最上面的柱子显示总和
需求 柱子需设置barMinHeight 在堆叠柱状图的最上面显示当前堆叠的总和 直接上代码吧 需要注意:设置barMinHeight时为了让0不显示,只能将0设置为null; 设置为null的柱子l ...
- 华为交换机5855设置ssh
配置思路 配置交换机密钥对 #生成RSA密钥对 设置vty登陆用户界面的认证方式为AAA认证 #设置远程认证方式 设置aaa用户信息 #本地用户名和密码 #本地用户服务类型 #本地用户授权等级 设置s ...
- Docker以过时,看Containerd怎样一统天下
Docker作为非常流行的容器技术,之前经常有文章说它被K8S弃用了,取而代之的是另一种容器技术containerd!其实containerd只是从Docker中分离出来的底层容器运行时,使用起来和D ...
- C++ 标准模板库(STL)——容器(Containers)的用法及理解
C++ 标准模板库(STL)中定义了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量(vector).队列(queue).栈(stack).set.map等.这次主要 ...
- C语言:强制类型转换
#include <stdio.h> //强制类型转换 //写法:(类型标识符)变量:(类型标识符)常量:(类型标识符)(表达式):三种格式 main() { float a=7.5f; ...
- C语言:打印所有char字符
#include <stdio.h> int main() { int aa; char bla; for(aa=0;aa<=255;aa++) { if(aa%10==0 and ...
- 【模拟】报名签到 luogu-4445
AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...
- 解决跨网段intouch嵌入视频问题
在自控项目中,一般会将视频网络和自控网络分开,分属于两个不同的逻辑网段,以避免局域网ip不够用的问题.这就造成了一个问题,如何实现在自控网络上位机访问摄像头并嵌入使用?这里其实很简单,因为这两个网络本 ...