题解 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! ...
随机推荐
- Kubernetes-22:kubelet 驱逐策略详解
为什么要驱逐pod? 在可用计算资源较少时,kubelet为保证节点稳定性,会主动地结束一个或多个pod以回收短缺地资源,这在处理内存和磁盘这种不可压缩资源时,驱逐pod回收资源的策略,显得尤为重要. ...
- ffiddler抓取手机(app)https包
很多同学有看过原文,但是按照原文还是没有设置成功(我就是其中一个)然后查了网上资料,在某些选项上进行增加,填写,配置通过.(和原文略有不同) 安装Fiddler,我们正常的流程在feiddler中设置 ...
- CTF-wtc_rsa_bbq-writeup
wtc_rsa_bbq 题目信息: 附件: cry200 解题思路: 1.观察cry200文件,发现该文件是一个二进制文件,用二进制模式查看,发现开头为50 4B 03 04,判断该文件是一个zip文 ...
- JAVA程序系统测试感受
JAVA课程才刚刚开始,就仿佛经历了一场劫难,让我们叫苦连天,苦不堪言.暑假学的一些皮毛java知识,到了真正需要写一个相对完整的软件系统,就如同废材一样,实在是用不上来.我看着小民哥布置的考试内容, ...
- 【转载】Java学习笔记
转载:博主主页 博主的其他笔记汇总 : 学习数据结构与算法,学习笔记会持续更新: <恋上数据结构与算法> 学习Java虚拟机,学习笔记会持续更新: <Java虚拟机> 学习Ja ...
- Requests方法 -- 参数关联
一.删除草稿箱1.参数这篇https://www.cnblogs.com/Teachertao/p/11144726.html 2.删除刚才保存的草稿 3.用 fiddler 抓包,抓到删除帖子的请求 ...
- PAT乙级:1015 德才论 (25分)
1015 德才论 (25分) 宋代史学家司马光在<资治通鉴>中有一段著名的"德才论":"是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人 ...
- npm命令,nrm命令,n命令, nvm命令
npm命令 npm/yarn config set registry https://registry.npm.taobao.org 设置淘宝镜像npm/yarn config get registr ...
- list实现从大到小排序
public static void main(String[] args) { List<Integer> list=new ArrayList<Integer>(); // ...
- Python中strip()、lstrip()、rstrip()函数的用法
Python中使用函数strip().lstrip().rstrip()来剔除字符串前后的特定字符 函数语法为:str.strip(chars) 返回值是一个新的字符串,不更改源字符串 其中,参数ch ...