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
 
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
 
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 预处理思路)的更多相关文章

  1. HDU 4455 Substrings ( DP好题 )

    这个……真心看不出来是个DP,我在树状数组的康庄大道上欢快的奔跑了一下午……看了题解才发现错的有多离谱. 参考:http://www.cnblogs.com/kuangbin/archive/2012 ...

  2. hdu 4455 Substrings(计数)

    题目链接:hdu 4455 Substrings 题目大意:给出n,然后是n个数a[1] ~ a[n], 然后是q次询问,每次询问给出w, 将数列a[i]分成若干个连续且元素数量为w的集合,计算每个集 ...

  3. hdu 4455 Substrings(找规律&DP)

    Substrings Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  4. HDU 4455 Substrings[多重dp]

    Substrings Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. HDU 4455.Substrings

    Substrings Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU - 4455 Substrings(非原创)

    XXX has an array of length n. XXX wants to know that, for a given w, what is the sum of the distinct ...

  7. HDU 4455 Substrings --递推+树状数组优化

    题意: 给一串数字,给q个查询,每次查询长度为w的所有子串中不同的数字个数之和为多少. 解法:先预处理出D[i]为: 每个值的左边和它相等的值的位置和它的位置的距离,如果左边没有与他相同的,设为n+8 ...

  8. 【HDOJ】4455 Substrings

    5000ms的时限,还挺长的.算法是DP.思路是找到ans[1..n]的结果,然后Query就容易做了.问题是怎么DP?考虑:1 1 2 3 4 4 5w=1: 7, 7 = 1 * 7w=2: 10 ...

  9. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

随机推荐

  1. Git 配置editor编辑器

    Git 配置editor编辑器 在ubuntu系统下,Git默认的编辑器是命令行,学名叫V什么的,使用起来诸多不便 在编辑提交日志的时候,用的比较多. 可以选择unbuntu默认的文档编辑器作为git ...

  2. 上证A股股指跌破1900

    上证A股股指跌破1900 有钱的同学赶紧买哦,机会难得哈哈!

  3. c语言中scanf()、printf()函数

    函数调用scanf(“%d”,  &weight) 包含两个参数:“%d” 和&weight.C用逗号来隔开函数调用中的多个参数: 但是printf()和scanf()函数比较特殊,其 ...

  4. c: c代码书写规范

    排版: 较长的语句或函数过程参数(>80字符)要分成多行书写, 长表达式要在低优先级操作符处划分新行,操作符放在新行之首, 划分出的新行要进行适当的缩进,使排版整齐,语句可读 参考: 1. 运算 ...

  5. 读取sd卡下图片,由图片路径转换为bitmap

    public Bitmap convertToBitmap(String path, int w, int h) {             BitmapFactory.Options opts = ...

  6. pytesser图片文本识别

    python图片文本识别使用的工具是PIL和pytesser.因为他们使用到很多的python库文件,为了避免一个个工具的安装,建议使用pythonxy,这个工具的介绍可参考baidu. pytess ...

  7. Linux less命令

    less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向前面翻 ...

  8. VS2010 安装 Boost 库 1.54

    Boost库被称为C++准标准库, 功能很是强大, 下面记录我在VS2010中安装使用Boost库的过程. 首先上官网http://www.boost.org/下载最新的Boost库, 我的版本是1_ ...

  9. getComputedStyle与currentStyle

    currentStyle:获取计算后的样式.也叫当前样式.终于样式. 长处:能够获取元素的终于样式.包含浏览器的默认值,而不像style仅仅能获取行间样式.所以更经常使用到. 注意:不能获取复合样式如 ...

  10. Android开发之SoundPool使用具体解释

    使用SoundPool播放音效 假设应用程序常常播放密集.急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了.由于MediaPlayer存在例如以下缺点: 1)      ...