HDU 4455 Substrings

来源:互联网 发布:中秋节祝福网页源码 编辑:程序博客网 时间:2024/05/22 17:24
#include <cstdio>#include <cstring>#include <queue>#include <iostream>#include <map>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const int maxn = 1000007;int n, q, a[maxn], sub[maxn], cnt[maxn], add[maxn], l[maxn];LL dp[maxn];bool vis[maxn];void init() {    sub[n+1] = 0; cnt[0] = 0;    memset(vis, false, sizeof(vis));    memset(add, 0, sizeof(add));    memset(l, 0, sizeof(l));    for(int i = n; i > 0; --i) {        if(!vis[a[i]]) sub[i] = sub[i+1]+1, vis[a[i]] = true;        else sub[i] = sub[i+1];    }//sub表示从i开始出现的数字的个数    for(int i = 1; i <= n; ++i) {        if(l[a[i]]) add[i-l[a[i]]]++, cnt[i] = cnt[i-1]+1;        else cnt[i] = cnt[i-1];        l[a[i]] = i; //l数组表示a[i]上次出现的位置    }//cnt数组表示当前位置之前出现的相同元素的个数    dp[1] = n;    for(int i = 1; i <= n; ++i) add[i] += add[i-1];    //add[len]数组表示ai = aj且j-i <= len + 1的数对个数    for(int i = 2; i <= n; ++i)        dp[i] = dp[i-1] + (n-i+1 - add[i-1]) - sub[n-i+2] + cnt[i-1];}int main() {    while(~scanf("%d", &n) && n) {        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);        init();        scanf("%d", &q);        while(q--) {            int tmp; scanf("%d", &tmp);            printf("%lld\n", dp[tmp]);        }    }}
0 0
原创粉丝点击