NBUT 1457 Sona

莫队算法+离散化

1.map会TLE,必须离散化做

2.long long会WA,__int64定义 %I64d输出输出能AC

3.注意输入的序列会爆int

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;

const int maxn = 100000 + 10;
int n, m;
__int64 tmp[maxn], a[maxn], lsh[maxn];
int cnt;
int pos[maxn];
__int64 c[maxn];
__int64 ans[maxn], Ans;
int L, R;
struct X
{
    int l, r, id;
}s[maxn];

bool cmp(const X&a, const X&b)
{
    if (pos[a.l] == pos[b.l]) return a.r < b.r;
    return a.l < b.l;
}

int f(__int64 x)
{
    int l = 1, r = cnt;
    while (l <= r)
    {
        int mid = (l + r) / 2;
        if (lsh[mid] < x) l = mid + 1;
        else if (lsh[mid]>x) r = mid - 1;
        else return mid;
    }
}

void LSH()
{
    sort(tmp + 1, tmp + 1 + n);
    cnt = 0, lsh[++cnt] = tmp[1];
    for (int i = 2; i <= n; i++)
    {
        if (tmp[i] == tmp[i - 1]) continue;
        lsh[++cnt] = tmp[i];
    }
    for (int i = 1; i <= n; i++) a[i] = (__int64)f(a[i]);
}

int main()
{
    while (~scanf("%d", &n)) 
    {
        memset(c, 0, sizeof c);
        int sz = sqrt(1.0*n);
        for (int i = 1; i <= n; i++)
        {
            pos[i] = i / sz;
            scanf("%I64d", &tmp[i]);
            a[i] = tmp[i];
        }
        LSH();

        scanf("%d", &m);
        for (int i = 1; i <= m; i++) {
            scanf("%d%d", &s[i].l, &s[i].r);
            s[i].id = i;
        }
        sort(s + 1, s + 1 + m, cmp);
        Ans = 0;
        for (int i = s[1].l; i <= s[1].r; i++)
        {
            Ans = Ans - c[a[i]] * c[a[i]] * c[a[i]];
            c[a[i]]++;
            Ans = Ans + c[a[i]] * c[a[i]] * c[a[i]];
        }
        ans[s[1].id] = Ans; L = s[1].l; R = s[1].r;

        for (int i = 2; i <= m; i++)
        {
            while (L < s[i].l)
            {
                Ans = Ans - c[a[L]] * c[a[L]] * c[a[L]];
                c[a[L]]--;
                Ans = Ans + c[a[L]] * c[a[L]] * c[a[L]];
                L++;
            }
            while (L > s[i].l)
            {
                L--;
                Ans = Ans - c[a[L]] * c[a[L]] * c[a[L]];
                c[a[L]]++;
                Ans = Ans + c[a[L]] * c[a[L]] * c[a[L]];
            }
            while (R < s[i].r)
            {
                R++;
                Ans = Ans - c[a[R]] * c[a[R]] * c[a[R]];
                c[a[R]]++;
                Ans = Ans + c[a[R]] * c[a[R]] * c[a[R]];
            }
            while (R > s[i].r)
            {
                Ans = Ans - c[a[R]] * c[a[R]] * c[a[R]];
                c[a[R]]--;
                Ans = Ans + c[a[R]] * c[a[R]] * c[a[R]];
                R--;
            }
            ans[s[i].id] = Ans;
        }

        for (int i = 1; i <= m; i++) printf("%I64d\n", ans[i]);
    }
    return 0;
}

 

posted @ 2016-04-20 18:53  Fighting_Heart  阅读(169)  评论(0编辑  收藏  举报