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; }