HDU 4455 Substrings

Substrings

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2340    Accepted Submission(s): 731


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
 

 

Source
 
解题:其实训练的时候基本都想到了,卡在如何把大的区间个数累加到小区间的个数上了。。。哎。。。
 
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 1000010;
 5 LL dp[maxn],delta;
 6 int d[maxn],pre[maxn],len[maxn],n,q;
 7 bool vis[maxn];
 8 int main() {
 9     while(~scanf("%d",&n),n) {
10         memset(len,0,sizeof len);
11         memset(vis,false,sizeof vis);
12         memset(pre,-1,sizeof pre);
13         for(int i = 0; i < n; ++i) {
14             scanf("%d",d+i);
15             len[i - pre[d[i]]]++;
16             pre[d[i]] = i;
17         }
18         for(int i = n-1; i >= 0; --i) len[i] += len[i+1];
19         dp[0] = 0;
20         dp[1] = n;
21         delta = 1;
22         vis[d[n-1]] = true;
23         for(int i = 2; i <= n; ++i) {
24             dp[i] = dp[i-1] + len[i] - delta;
25             if(!vis[d[n-i]]) {
26                 delta++;
27                 vis[d[n-i]] = true;
28             }
29         }
30         scanf("%d\n",&q);
31         while(q--) {
32             scanf("%d",&n);
33             printf("%I64d\n",dp[n]);
34         }
35     }
36     return 0;
37 }
View Code

 

posted @ 2015-09-02 18:53  狂徒归来  阅读(247)  评论(0编辑  收藏  举报