zoukankan      html  css  js  c++  java
  • 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
    ",&q);
    31         while(q--) {
    32             scanf("%d",&n);
    33             printf("%I64d
    ",dp[n]);
    34         }
    35     }
    36     return 0;
    37 }
    View Code
  • 相关阅读:
    linux之uniq
    shell之sort
    tr命令的使用
    AWK 简明教程
    Word Frequency
    10亿个数中选出最大的100个数
    代理模式(也称委托模式)
    java内存相关
    Two Sum
    Java的集合
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4779273.html
Copyright © 2011-2022 走看看