HDU 4455 Substrings

      又是一道看了别人思路才写出来的题目。。。。说是说到现在做了不少题目,而且有很多有难度的题,但其实几乎没有自己独立思考想出来的,独立思考太重要了,这样下去,做一万道题也是个渣。。。。

这个人的解题报告写的比较好,http://blog.csdn.net/gotoac/article/details/8188437,看了他的思路后自己实现了下,还有很多细节问题,比如要用__int64,比如怎么预处理。

这道题我用了set,但是几乎每次用set都A不了,而且都出一些特别特别难找的错误,只能老老实实做预处理。这道题有一个很精妙的地方,就是先把每次相隔距离为1,2,3。。。。距离的数字找出来,然后每次减掉不符合要求的,剩下的就是符合要求的。开始我只能用最呆板的方法去做,虽然思想是对的,但是会超时。

比如 测试数据为 1,1,2,3,4,4,5。dis数组保存距离为i的数字有多少个。对这个测试数据来说,dis[1] = 3,dis[2] = 1,dis[3] = 1,dis[4] = 1,dis[5] = 1,dis[6] = 0,dis[7] = 1。先假设每个数加进来都符合要求,然后每次算dp[i]的时候,新加入的符合要求的数的个数就等于total-(dis[1] + dis[2] + dis[3] + ..... + dis[i-1]).

#pragma warning (disable:4786)
#include<iostream>
#include<map>
#include<algorithm>
#include<memory>
#include<set>
using namespace std;

int a[1000006],tag[1000006],len[1000005],dp1[1000005];
__int64 dp[1000005];

int main()
{
    int n,m,total;
    while(scanf("%d",&n),n)
    {
        memset(tag,0,sizeof(tag));
        memset(len,0,sizeof(len));
        for(int i = 1;i <= n;++i)
        {
            scanf("%d",&a[i]);
            len[i - tag[a[i]]]++;
            tag[a[i]] = i;
        }
        memset(tag,0,sizeof(tag));
        dp1[0] = 0;
        for(i = 1;i <= n;++i)
        {
            dp1[i] = dp1[i - 1];
            if(tag[a[n - i + 1]] == 0)
                dp1[i]++;
            tag[a[n - i + 1]] = 1;
        }
		dp[1] = total = n;
        for(i = 2;i <= n;++i)
        {
            dp[i] = dp[i-1] - dp1[i-1];
            total -= len[i - 1];
            dp[i] += total;
        }
        scanf("%d",&m);
        while(m--)
        {
            int q;
            scanf("%d",&q);    
            printf("%I64d\n",dp[q]);
        }
    }
    return 0;
}

    

猜你喜欢

转载自blog.csdn.net/a549875231/article/details/12132519