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): 3240    Accepted Submission(s): 990


    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
    We have carefully selected several similar problems for you:  6018 6017 6016 6015 6014 
     
    题意:有n个数,q个询问。求每次询问的连续长度为w的子数组权值的和。数组的权值为数组内不相同的数的个数。
     
    思路:

    拿样例写一下

    1: {1},           {1},           {2},        {3},            {4},          {4},          {5}

    2: {1,1},        {1,2},        {2,3},      {3,4},         {4,4},       {4,5} 

    3: {1,1,2},     {1,2,3},     {2,3,4},    {3,4,4},      {4,4,5} 

    4: {1,1,2,3},  {1,2,3,4},  {2,3,4,4},  {3,4,4,5} 

    ...

    容易发现可以得出一个发现:

    长度为w的值肯定包含长度为w-1的值减去最后一个字数组的权值和

    例:

    2: {1,1} ,  {1,2} ,    {2,3} ,    {3,4} ,    {4,4} ,   {4,5} 

    3: {1,1,2} , {1,2,3} , {2,3,4} , {3,4,4} , {4,4,5

    dp[3] = dp[2] - 权值[{4,5}] + ?

    而'?'就表示添加上那些标蓝色的数之后要添加的值.

    设某个标蓝色的数为a[i],另外一个和它相等的且和它最近的数为a[j],且i>j

    如果i-j>w的话那么添上这个标蓝的数就可以使得dp[w]+1

    所以我们只要求出cnt[dis]即可,dis既某数离在它之前且相等的且和它最近的数的距离.

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int MAXN=1e6+100,inf=0x3f3f3f3f,mod=1e9+7;
    #define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))
    int a[MAXN];
    int cnt[MAXN],dp[MAXN];
    ll sign[MAXN];
    void run(int n)
    {
        memset(cnt,0,sizeof(cnt));
        memset(sign,0,sizeof(sign));
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            int x=i-sign[a[i]];
            cnt[i-sign[a[i]]]++;
            sign[a[i]]=i;   ///sign[i]表示i的位置
            //cout<<x<<" "<<cnt[x]<<endl;
        }
        memset(dp,0,sizeof(dp));
        memset(sign,0,sizeof(sign));
        for(int i=n,t=1; i>0; i--,t++)
        {
            if(sign[a[i]]) dp[t]=dp[t-1];
            else dp[t]=dp[t-1]+1,sign[a[i]]=1;  ///sign[i]标记i是否出现过
        }
        memset(sign,0,sizeof(sign));
        int t=n;
        for(int i=1; i<=n; i++)
        {
            sign[i]=sign[i-1]-ll(dp[i-1]);
            t-=cnt[i-1];
            sign[i]+=t;
        }
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)&&n!=0)
        {
            run(n);
            int q;
            scanf("%d",&q);
            while(q--)
            {
                int w;
                scanf("%d",&w);
                cout<<sign[w]<<endl;
            }
        }
        return 0;
    }
    View Code
    I am a slow walker,but I never walk backwards.
  • 相关阅读:
    第二次站立会议4
    第二次站立会议3
    建议总结
    对搜狗输入法的个人评价
    第二期站立会议10
    典型用户和用户场景描述
    第二期站立会议9
    第二期站立会议8
    第二期站立会议7
    第二期站立会议6
  • 原文地址:https://www.cnblogs.com/GeekZRF/p/6627753.html
Copyright © 2011-2022 走看看