首页 > 代码库 > hdu 4455 Substrings (DP 预处理思路)
hdu 4455 Substrings (DP 预处理思路)
Substrings
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1727 Accepted Submission(s): 518
Problem Description
XXX has an array of length n. XXX wants to know that, for a given w, what is the sum of the distinct elements’ number in all substrings of length w. For example, the array is { 1 1 2 3 4 4 5 } When w = 3, there are five substrings of length 3. They are (1,1,2),(1,2,3),(2,3,4),(3,4,4),(4,4,5)
The distinct elements’ number of those five substrings are 2,3,3,2,2.
So the sum of the distinct elements’ number should be 2+3+3+2+2 = 12
The distinct elements’ number of those five substrings are 2,3,3,2,2.
So the sum of the distinct elements’ number should be 2+3+3+2+2 = 12
Input
There are several test cases.
Each test case starts with a positive integer n, the array length. The next line consists of n integers a1,a2…an, representing the elements of the array.
Then there is a line with an integer Q, the number of queries. At last Q lines follow, each contains one integer w, the substring length of query. The input data ends with n = 0 For all cases, 0<w<=n<=106, 0<=Q<=104, 0<= a1,a2…an <=106
Each test case starts with a positive integer n, the array length. The next line consists of n integers a1,a2…an, representing the elements of the array.
Then there is a line with an integer Q, the number of queries. At last Q lines follow, each contains one integer w, the substring length of query. The input data ends with n = 0 For all cases, 0<w<=n<=106, 0<=Q<=104, 0<= a1,a2…an <=106
Output
For each test case, your program should output exactly Q lines, the sum of the distinct number in all substrings of length w for each query.
Sample Input
7 1 1 2 3 4 4 5 3 1 2 3 0
Sample Output
7 10 12
1、 很明显,长度为1的答案为dp[1]=n;
2、 长度为2的为dp[2]=dp[1]+x-y=7+4-1=10;
X为增加的一个数和前边不同的个数,{1,1},{1,2},{2,3},{3,4},{4,4},{4,5} 为4;
Y为去掉的不足2的区间有几个不同数字,长度为1的最后一个区间{5},需要舍去,为1;
3、
长度为3的为dp[3]=dp[2]+x-y=10+4-2=12;
X为增加的一个数和前边不同的个数,{1,1,2},{1,2,3},{2,3,4},{3,4,4},{4,4,5}为4;
Y为去掉的不足3的区间有几个不同数字,长度为2的最后一个区间{4,5},需要舍去,为2;
所以,我们需要得到当前数字和它上次出现的位置差的大小。具体实现看代码。。
#include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> using namespace std; #define N 1000005 #define LL __int64 const int inf=0x1f1f1f1f; int a[N],len[N],pre[N],vis[N],f[N]; LL dp[N]; int main() { int i,n,m; while(scanf("%d",&n),n) { memset(pre,-1,sizeof(pre)); //记录一个值上次出现的位置 memset(len,0,sizeof(len)); //len[i]:有几个间隔为i的数 memset(dp,0,sizeof(dp)); //记录最终答案 for(i=0;i<n;i++) { scanf("%d",&a[i]); len[i-pre[a[i]]]++; pre[a[i]]=i; } for(i=n-1;i>=0;i--) len[i]+=len[i+1]; memset(f,0,sizeof(f)); //f[i]从后往前记录后i个数有几个不同值 memset(vis,0,sizeof(vis)); for(i=1;i<n;i++) { f[i]=f[i-1]; if(!vis[a[n-i]]) { vis[a[n-i]]=1; f[i]++; } } dp[1]=n; for(i=2;i<=n;i++) dp[i]=dp[i-1]+len[i]-f[i-1]; scanf("%d",&m); while(m--) { scanf("%d",&i); printf("%I64d\n",dp[i]); } } return 0; }
hdu 4455 Substrings (DP 预处理思路)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。