# 51nod 1712 区间求和

#### Code

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define ll long long
#define db double
#define uint unsigned int
#define N 3000100
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define swap(T, a, b) ({T ttt = a; a = b; b = ttt;})
int n, lrk[N], rrk[N], pre[N], next[N], pos[N];
uint a[N], decA[N], decB[N], f[N], g[N], Ans = 0;
void G(uint &w) {
w = 0; char c = getchar();
while (c > '9' || c < '0') c = getchar();
while (c >= '0' && c <= '9') { w = w * 10 + c - '0'; c = getchar(); }
}
uint Mult(uint a, uint b)
{
uint s = 0;
while (b) {
if (b & 1) s += a;
a += a; b >>= 1;
}
return s;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
G(a[i]);
memset(pos, 0, sizeof(pos));
for (int i = 1; i <= n; i++)
{
pre[i] = pos[a[i]]; pos[a[i]] = i;
lrk[i] = lrk[pre[i]] + 1;
decA[i] = decA[pre[i]] + pre[i];
}
memset(pos, 0, sizeof(pos));
for (int i = n; i >= 1; i--)
{
next[i] = pos[a[i]]; pos[a[i]] = i;
rrk[i] = rrk[next[i]] + 1;
decB[i] = decB[next[i]] + next[i];
}
for (int i = 1; i <= n; i++)
{
if (rrk[i] == 1)
{
next[i] = i+n; pre[i+n] = i;
lrk[next[i]] = lrk[i] + 1;
decA[i+n] = decA[i] + i;
}
if (lrk[i] == 1)
{
pre[i] = i+n*2; next[i+n*2] = i;
rrk[pre[i]] = rrk[i] + 1;
decB[i+n*2] = decB[i] + i;
}
}
for (int i = 1; i <= n; i++)
f[i] = f[i-1] + i*rrk[i] - decA[next[i-1]];
for (int i = n; i >= 1; i--)
g[i] = g[i+1] + i*lrk[i] - decB[pre[i+1]];
for (int i = 1; i <= n; i++)
f[i] = f[i] + g[i] - i*2;
memset(g, 0, sizeof(g));
memset(decA, 0, sizeof(decA));
for (int i = 1; i <= n; i++)
{
decA[i] = decA[pre[i]] + (pre[i] >= 1 && pre[i] <= n);
if (rrk[i] == 1) decA[i+n] = decA[i] + 1;
}
for (int i = 1; i <= n; i++)
{
g[i] = g[i-1] + rrk[i] - decA[next[i-1]];
f[i] = Mult(g[i] - 1, i) * 2 - f[i];
Ans += Mult(f[i], a[i]);
}
std::cout << Ans << std::endl;
return 0;
}

posted @ 2016-11-28 09:24  zkGaia  阅读(269)  评论(0编辑  收藏