首页 > 代码库 > BZOJ 3781 小B的询问 莫队算法
BZOJ 3781 小B的询问 莫队算法
题目大意:一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。
思路:莫队走起。
CODE:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 50010 using namespace std; int belong[MAX],block_size; struct Ask{ int x,y,id; bool operator <(const Ask &a)const { if(belong[x] == belong[a.x]) return y <= a.y; return belong[x] < belong[a.x]; } void Read(int p) { scanf("%d%d",&x,&y); id = p; belong[p] = p / block_size; } }ask[MAX]; int cnt,asks; int src[MAX]; int v[MAX],now; int ans[MAX]; int main() { cin >> cnt >> asks; scanf("%*d"); block_size = sqrt(cnt); for(int i = 1; i <= cnt; ++i) scanf("%d",&src[i]); for(int i = 1; i <= asks; ++i) ask[i].Read(i); sort(ask + 1,ask + asks + 1); int l = 1,r = 0; for(int temp,i = 1; i <= asks; ++i) { while(r < ask[i].y) { temp = src[++r]; now -= v[temp] * v[temp]; ++v[temp]; now += v[temp] * v[temp]; } while(l > ask[i].x) { temp = src[--l]; now -= v[temp] * v[temp]; ++v[temp]; now += v[temp] * v[temp]; } while(l < ask[i].x) { temp = src[l++]; now -= v[temp] * v[temp]; --v[temp]; now += v[temp] * v[temp]; } while(r > ask[i].y) { temp = src[r--]; now -= v[temp] * v[temp]; --v[temp]; now += v[temp] * v[temp]; } ans[ask[i].id] = now; } for(int i = 1; i <= asks; ++i) printf("%d\n",ans[i]); return 0; }
BZOJ 3781 小B的询问 莫队算法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。