mo +离散化 HDU3333(听说还有离线线段树的做法 )

http://acm.hdu.edu.cn/showproblem.php?pid=3333

mo套map会T,卡了一个logN,所以要先离散化处理

#define _CRT_SECURE_NO_WARNINGS
#include<cmath>
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
using namespace std;
#define rep(i,t,n)  for(int i =(t);i<=(n);++i)
#define per(i,n,t)  for(int i =(n);i>=(t);--i)
#define mmm(a,b) memset(a,b,sizeof(a))
const int maxn = 1e5+ 5;
map<int, int> mmp;

struct node {
    int l, r, id;

}Q[maxn];
long long ans[maxn];

int a[maxn], b[maxn],cnt[maxn],pos[maxn];
int n, m, k;
int L = 1, R = 0;
long long Ans = 0;
bool cmp(node a, node b) {
    if (pos[a.l] == pos[b.l])
        return a.r < b.r;
    return pos[a.l] < pos[b.l];

}
void add(int x) {

    if (cnt[b[x]]>0)cnt[b[x]]++;
    else Ans += a[x],cnt[b[x]] = 1;

}
void del(int x) {
    cnt[b[x]]--;
    if (cnt[b[x]] == 0) Ans -= a[x];
}

int main() {
    int t; scanf("%d", &t);
    while (t--) {
        Ans = 0;
        mmp.clear();
        mmm(cnt, 0);
        L = 1, R = 0;
        scanf("%d", &n);
        int sz = sqrt(n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            pos[i] = i / sz;
        }
        int id = 0;
        rep(i, 1, n) {
            if (!mmp.count(a[i]))mmp[a[i]] = ++id;
            b[i] = mmp[a[i]];
        }
        scanf("%d", &m);
        for (int i = 1; i <= m; i++) {
            scanf("%d%d", &Q[i].l, &Q[i].r);
            Q[i].id = i;
        }
        sort(Q + 1, Q + 1 + m, cmp);

        for (int i = 1; i <= m; i++) {
            while (R < Q[i].r) {
                R++;
                add(R);
            }
            while (L > Q[i].l) {
                L--;
                add(L);
            }
            while (R > Q[i].r) {
                del(R);
                R--;

            }
            while (L < Q[i].l) {
                del(L);
                L++;
            }
            ans[Q[i].id] = Ans;
            //
        }
        for (int i = 1; i <= m; i++)
            //cout << ans[i] << endl;
            printf("%lld\n", ans[i]);
        //cin >> n;
    }
    cin >> t;
    return 0;
}

 

posted @ 2018-07-18 20:07  SuuTTT  阅读(242)  评论(0编辑  收藏  举报