博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj3781】小B的询问 莫队算法
阅读量:4577 次
发布时间:2019-06-08

本文共 1428 字,大约阅读时间需要 4 分钟。

原文地址:http://www.cnblogs.com/GXZlegend/p/6803821.html


题目描述

小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。小B请你帮助他回答询问。

输入

第一行,三个整数N、M、K。
第二行,N个整数,表示小B的序列。
接下来的M行,每行两个整数L、R。

输出

M行,每行一个整数,其中第i行的整数表示第i个询问的答案。

样例输入

6 4 3

1 3 2 1 1 3
1 4
2 6
3 5
5 6

样例输出

6

9
5
2


题解

莫队算法模板题,优雅的暴力

设原来有n个某颜色,加1后对答案的贡献为(n+1)^2-n^2=2*n+1,减1对答案的贡献为(n-1)^2-n^2=-(2*n-1)。

然后各种区间平移得到答案。

#include 
#include
#include
#define N 50010using namespace std;struct data{ int l , r , b , p;}a[N];int c[N];long long ans[N] , cnt[N];bool cmp(data x , data y){ return x.b == y.b ? x.r < y.r : x.b < y.b;}int main(){ int n , m , k , i , si , lp = 1 , rp = 0 , now = 0; scanf("%d%d%d" , &n , &m , &k); si = (int)sqrt(n); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &c[i]); for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &a[i].l , &a[i].r) , a[i].b = (a[i].l - 1) / si , a[i].p = i; sort(a + 1 , a + m + 1 , cmp); for(i = 1 ; i <= m ; i ++ ) { while(lp < a[i].l) now -= 2 * cnt[c[lp]] - 1 , cnt[c[lp]] -- , lp ++ ; while(rp > a[i].r) now -= 2 * cnt[c[rp]] - 1 , cnt[c[rp]] -- , rp -- ; while(lp > a[i].l) lp -- , now += 2 * cnt[c[lp]] + 1 , cnt[c[lp]] ++ ; while(rp < a[i].r) rp ++ , now += 2 * cnt[c[rp]] + 1 , cnt[c[rp]] ++ ; ans[a[i].p] = now; } for(i = 1 ; i <= m ; i ++ ) printf("%lld\n" , ans[i]); return 0;}

 

转载于:https://www.cnblogs.com/GXZlegend/p/6803821.html

你可能感兴趣的文章
第十八周 12.27-1.2
查看>>
C# IP地址字符串和数值转换
查看>>
TCHAR和CHAR类型的互转
查看>>
常用界面布局
查看>>
C语言—— for 循环
查看>>
IBM lotus9.0测试版即将公测
查看>>
xml常用方法
查看>>
Cube Stacking(并差集深度+结点个数)
查看>>
AndroidStudio3更改包名失败
查看>>
jq 删除数组中的元素
查看>>
js URL中文传参乱码
查看>>
Leetcode 367. Valid Perfect Square
查看>>
UVALive 3635 Pie(二分法)
查看>>
win系统查看自己电脑IP
查看>>
Backup&recovery备份和还原 mysql
查看>>
一道面试题及扩展
查看>>
Unity 3D 我来了
查看>>
setup elk with docker-compose
查看>>
C++ GUI Qt4学习笔记03
查看>>
Java基础回顾 —反射机制
查看>>