zoukankan      html  css  js  c++  java
  • HDU 4455 Substrings[多重dp]

    Substrings

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


    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
     
    Recommend

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=1e6+5;
    int n,num[N];
    int cx[N],add[N],lnc[N];
    long long f[N];
    void Discretization(){
        memset(cx,0,sizeof cx);
        memset(lnc,0,sizeof lnc);
        for(int i=1;i<=n;i++){
            if(!cx[num[n-i+1]]){
                cx[num[n-i+1]]=1;
                lnc[i]=lnc[i-1]+1;
            }
            else{
                lnc[i]=lnc[i-1];
            }
        }
        memset(cx,0,sizeof cx);
        memset(add,0,sizeof add);
        for(int i=1;i<=n;i++){
            add[i-cx[num[i]]]++;
            cx[num[i]]=i;
        }
    }
    void DynamicProgramming(){
        memset(f,0,sizeof f);
        f[1]=n;int delta=n;
        for(int i=2;i<=n;i++){
            f[i]=f[i-1]-lnc[i-1];
            delta-=add[i-1];
            f[i]+=delta;
        }
    }
    void Solution(){
        int Q,x;
        for(scanf("%d",&Q);Q--;) scanf("%d",&x),printf("%lld
    ",f[x]);
    }
    int main(){
        while((~scanf("%d",&n))&&n){
            for(int i=1;i<=n;i++) scanf("%d",&num[i]);
            Discretization();
            DynamicProgramming();
            Solution();
        }
        return 0;
    }
  • 相关阅读:
    POJ2594拐点弯的二分
    poj1523赤裸裸的割点
    POJ2239二分匹配
    对java多线程的一些浅浅的理解
    POJ3216 最小路径覆盖
    POJ1719二分匹配
    [算法]本学期算法作业
    [离散数学II]2017.3.29
    [离散数学II]2017.3.29
    [概率论]2017.3.29
  • 原文地址:https://www.cnblogs.com/shenben/p/6721579.html
Copyright © 2011-2022 走看看