Topic Link: Click to open the link
Ideas:
We use d[i] to denote the answer of length I. Then we can write the sample data to see if we can push it. Can be found, d[i] = d[i-1]-last[i-1] + (n-i+1)-dist[i].
Last[i] Indicates the number of different numbers from the backward I length, that is, the last subsequence of D[i-1] is thrown, and then d[i] may be added (N-i + 1) than d[i-1], and then we subtract the non-conforming requirements. When the competition was launched, it is not clear, suggest to push yourself.
See the code for details:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < string> #include <vector> #include <stack> #include <bitset> #include <cstdlib> #include < cmath> #include <set> #include <list> #include <deque> #include <map> #include <queue> Using namespace Std;typedef long Long ll;const double PI = ACOs ( -1.0); const double EPS = 1e-6;const int INF = 1000000000;c onst int maxn = 1e6+5;int T,N,M,R,A[MAXN],LAST[MAXN],DIST[MAXN], q, x, P[maxn];ll d[maxn];bool hehe[maxn];int main () { while (~SCANF ("%d", &n) && N) {memset (d, 0, sizeof (d)); memset (hehe, 0, sizeof (hehe)); memset (Dist, 0, sizeof (Dist)); D[1] = n; for (int i = 1; I <= n; i++) {scanf ("%d", &a[i]); } int cnt = 1; memset (p, 0, sizeof (p)); for (int i = n; I >= 1; i--) {if (P[a[i]]) last[cnt] = last[cnt-1]; else {P[a[i]] = 1; LAST[CNT] = last[cnt-1] + 1; } cnt++; } memset (p, 0, sizeof (p)); for (int i = 1; I <= n; i++) {if (P[a[i]]) {dist[i-p[a[i]]+1]++; Hehe[i] = 1; P[a[i]] = i; } else p[a[i]] = i; } for (int i = 1; I <= n; i++) {if (hehe[i-1]) dist[i] + = dist[i-1]-1; else Dist[i] + = dist[i-1]; } for (int i = 2; I <= n; i++) {d[i] = D[i-1]-(LL) Last[i-1] + (LL) (N-i + 1)-(ll) dist[i]; } scanf ("%d", &q); while (q--) {scanf ("%d", &x); printf ("%i64d\n", d[x]); }} return 0;}
HDU 4455 substrings (DP)