hdu 4455 Substrings 预处理+递推
来源:互联网 发布:linux iostat命令详解 编辑:程序博客网 时间:2024/05/21 17:43
给一个长度不超过10^6的序列,再给一些询问,对每个询问k,输出原序列中,每个长度为k的连续子序列种不同数字的个数的和。一眼看上去一点思路都没有...看题名难免会往SA和KMP上想..结果都没有什么好想法....昨天听@qian99大神说了下思路,豁然开朗= =...
结合样例说一下吧,
长度为1 1 1 2 3 4 4 5
长度为2 11 12 23 34 44 45
112 123 234 344 445
1123 1234 2344 3445
11234 12344 23445
112344 123445
1123445
不难发现,一层一层推下来,发现下一层都是上一层除了最后一组的数,后面添加一个数,如果添加的这个数在这组没出现过,就加一。这样,下一层的答案都是由上一层的答案剪掉上一层最后一组不同的数字个数再加上添加之后新增加的不同的数字个数,即dp[i]=dp[i-1]+A-B; 而B的值明显可以递推一下预处理出来,A的话我的写法对每个位置记录一下上一次自己出现的位置pos[i],没有就是0.然后开一个数组c[i]表示每一位和他上次出现的位置不大于i的有多少种情况。因为从上往下,添加的数每次都少一个,所以在递推c[i]的时候对当前的第一个数要特判一下,据题写法看代码吧。
#include <iostream>#include <cstdio>#include <algorithm>#include <memory.h>#include <cmath>#include <queue>#include <stack>#include <map>using namespace std;typedef long long ll;const int maxn=1000000+1000;int n,m,p,q,k;int last[maxn];int pos[maxn];int a[maxn];ll c[maxn];int sub[maxn];bool vis[maxn];ll dp[maxn];int main(){// freopen("in.txt","r",stdin); while(scanf("%d",&n) && n) { memset(last,0,sizeof last); memset(pos,0,sizeof pos); memset(c,0,sizeof c); for (int i=1; i<=n; i++) { scanf("%d",&a[i]); } for (int i=1; i<=n; i++) { pos[i]=last[a[i]]; last[a[i]]=i; }// for (int i=1; i<=n; i++)// printf("%d ",pos[i]);// printf("\n");// for (int i=1; i<=n; i++)// printf("%d ",last[i]);// printf("\n"); for (int i=1; i<=n; i++) { if (!pos[i]) continue; c[i-pos[i]]++; } for (int i=2; i<=n; i++) { c[i]+=c[i-1]; if (pos[i]) c[i]-=1; } memset(vis,false,sizeof vis); memset(sub,0,sizeof sub); vis[a[n]]=true; sub[1]=1; for (int i=n-1; i>=1; i--) { sub[n-i+1]=sub[n-i]; if (!vis[a[i]]) sub[n-i+1]++,vis[a[i]]=true; } memset(dp,0,sizeof dp); dp[1]=(ll)n; for (int i=2; i<=n; i++) { dp[i]=dp[i-1]-(ll)sub[i-1]+(ll)(n-i+1-c[i-1]); } scanf("%d",&m); while(m--) { scanf("%d",&k); printf("%I64d\n",dp[k]); } } return 0;}
- hdu 4455 Substrings 预处理+递推
- hdu 4455 Substrings(树状数组+递推)
- HDU 4455 Substrings(递推+优化)
- HDU-4455 Substrings DP递推
- HDU 4455 Substrings(预处理+dp)
- HDU 4455 Substrings --递推+树状数组优化
- hdu 4455 Substrings (DP 预处理思路)
- HDOJ 4455 Substrings 递推+树状数组
- hdu 4455 Substrings
- hdu 4455 Substrings
- hdu 4455 Substrings
- HDU 4455 Substrings
- dp-hdu-4455-Substrings
- HDU 4455 Substrings
- HDU 4455 Substrings
- HDU 4455 Substrings dp
- HDU 4455 Substrings
- HDU 4455 Substrings
- 二叉树
- 对称排序(稳定排序问题)
- 动态输入日期与时间
- 基于STM32F103的悬挂运动控制系统项目总结
- POJ 3321 - Apple Tree DFS出时间搓,树状数组统计维护..
- hdu 4455 Substrings 预处理+递推
- JavaIO之标准输入输出(二)
- magento常用函数列表
- Linux2.6.6 内核下 ACPI PCI Hot-Plug 的实现机制(上)
- tcp头部在linux中的实现tcphdr
- 预编译的作用和目的
- 重玩快排
- 妙趣横生的算法之栈的操作
- 【Linux软件安装】Ubuntu12.04:matlab2010a