NBUT--1457(莫队,分块)

2015-04-29 22:23:27

题目:和 bzoj 2038 基本一样的题... 加大了数据范围,简化了区间转移。比较裸的莫队用分块实现。

  (1)别用map,先离散化比较块。

  (2)预处理出所有的三次方能提高效率。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define MP(a,b) make_pair(a,b)
#define PB(a) push_back(a)

typedef long long ll;
typedef pair<int,int> pii;
const double eps = 1e-8;
const int INF = (1 << 30) - 1;
const int MAXN = 100010;

int N,Q,block,vsz;
int v[MAXN],vb[MAXN];
ll val,num[MAXN],Cb[MAXN];

struct Node{
    int x,y,id,bid;
    ll A;
}p[MAXN];

bool cmp(Node a,Node b){ return a.bid == b.bid ? a.y < b.y : a.bid < b.bid; }
bool cmp_id(Node a,Node b){ return a.id < b.id; }

void Update(int l,int r,int add){
    for(int i = l; i <= r; ++i){
        val -= Cb[num[v[i]]];
        num[v[i]] += add;
        val += Cb[num[v[i]]];
    }
}

void Block(){
    val = 0;
    memset(num,0,sizeof(num));
    sort(p + 1,p + Q + 1,cmp);
    for(int i = 1,l = 1,r = 0; i <= Q; ++i){
        if(l < p[i].x) Update(l,p[i].x - 1,-1);
        if(p[i].x < l) Update(p[i].x,l - 1,1);
        if(r < p[i].y) Update(r + 1,p[i].y,1);
        if(p[i].y < r) Update(p[i].y + 1,r,-1);
        p[i].A = val;
        l = p[i].x,r = p[i].y;
    }
    sort(p + 1,p + Q + 1,cmp_id);
    for(int i = 1; i <= Q; ++i)
        printf("%I64d\n",p[i].A);
}

int main(){
    while(scanf("%d",&N) != EOF){
        for(int i = 1; i <= N; ++i) Cb[i] = (ll)i * i * i;
        block = (int)sqrt(1.0 * N);
        for(int i = 1; i <= N; ++i){
            scanf("%d",&v[i]);
            vb[i] = v[i];
        }
        sort(vb + 1,vb + N + 1);
        vsz = (int)(unique(vb + 1,vb + N + 1) - vb);
        for(int i = 1; i <= N; ++i)
            v[i] = lower_bound(vb + 1,vb + N + 1,v[i]) - vb;
        scanf("%d",&Q);
        for(int i = 1; i <= Q; ++i){
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].id = i;
            p[i].bid = p[i].x / block;
        }
        Block();
    }
    return 0;
}

 

posted @ 2015-04-29 22:26  Naturain  阅读(125)  评论(0编辑  收藏  举报