【NOI2017模拟6.3】子序列 矩阵乘法+DP

准队爷富榄出的题目,被虐的不要不要的,打了个40分还被卡常。。。 题意:给你1个长度为n的字符串,每次给出询问l,r问l,r中有多少个本质不同的子序列。 n,q<=1e5。 一开始差点连题目都没理解清楚,子序列一定不连续,子串才连续= =。。一个并不显然的dp是设f[i][j]表示第i位为j的答案,那么初始f[i][s[i]]=1,然后f[i][j]+=sigma(f[i][1-9]),然后我
摘要由CSDN通过智能技术生成

准队爷富榄出的题目,被虐的不要不要的,打了个40分还被卡常。。。
题意:给你1个长度为n的字符串,每次给出询问l,r问l,r中有多少个本质不同的子序列。
n,q<=1e5。
一开始差点连题目都没理解清楚,子序列一定不连续,子串才连续= =。。

一个并不显然的dp是设f[i][j]表示第i位为j的答案,那么初始f[i][s[i]]=1,然后f[i][j]+=sigma(f[i][1-9]),然后我们发现好像这个跟i的关系不太大,然后把第一维舍去,变成f[i],那么很明显,n^2的做法就是每次枚举l,r之间的时候ans=sigma(f[i]),f[i]=sigma(f[j])(j=1-9),然后可能我姿势不对被卡了10分。。

然后我就不大会了,后来看了题解发现自己是个煞笔。
为什么不设一个能递推的呢???
考虑如何求一个序列的子序列个数,有一个简单的 Dp 转移
若 S[i]=c,则F[i][c] = ∑F[i − 1][k], F[i][k] = F[i − 1][k],
这个很明显可以用矩阵加速= =
统计前缀积和逆矩阵的前缀积,然后答案用两个前缀积搞搞就好了。
注意预处理的地方。
然后就是富榄说矩阵乘法改变一下j,k的顺序可以做到寻址优化,蒙蔽了= =而且居然真的快了100多ms。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值