离线+分块

将n个数分成sqrt(n)块。

对所有询问进行排序,排序标准:

      1. Q[i].left /block_size < Q[j].left / block_size (块号优先排序)

      2. 如果1相同,则 Q[i].right < Q[j].right (按照查询的右边界排序)

问题求解:

从上一个查询后的结果推出当前查询的结果。(这个看程序中query的部分)

如果一个数已经出现了x次,那么需要累加(2*x+1)*a[i],因为(x+1)^2*a[i] = (x^2 +2*x + 1)*a[i],x^2*a[i]是出现x次的结果,(x+1)^2 * a[i]是出现x+1次的结果。

时间复杂度分析:

排完序后,对于相邻的两个查询,left值之间的差最大为sqrt(n),则相邻两个查询左端点移动的次数<=sqrt(n),总共有t个查询,则复杂度为O(t*sqrt(n))。

又对于相同块内的查询,right端点单调上升,每一块所有操作,右端点最多移动O(n)次,总块数位sqrt(n),则复杂度为O(sqrt(n)*n)。

right和left的复杂度是独立的,因此总的时间复杂度为O(t*sqrt(n)  +  n*sqrt(n))。

代码如下:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <cmath>
  6. using namespace std;
  7. #define N 200100
  8. typedef long long ll;
  9. ll a[N], cnt[N*], ans[N], res;
  10. int L, R;
  11.  
  12. struct node {
  13. int x, y, l, p;
  14. } q[N];
  15. bool cmp(const node &x, const node &y) {
  16. if (x.l == y.l) return x.y < y.y;
  17. return x.l < y.l;
  18. }
  19. void query(int x, int y, int flag) {
  20. if (flag) {
  21. for (int i=x; i<L; i++) {
  22. res += ((cnt[a[i]]<<)+)*a[i];
  23. cnt[a[i]]++;
  24. }
  25. for (int i=L; i<x; i++) {
  26. cnt[a[i]]--;
  27. res -= ((cnt[a[i]]<<)+)*a[i];
  28. }
  29. for (int i=y+; i<=R; i++) {
  30. cnt[a[i]]--;
  31. res -= ((cnt[a[i]]<<)+)*a[i];
  32. }
  33. for (int i=R+; i<=y; i++) {
  34. res += ((cnt[a[i]]<<)+)*a[i];
  35. cnt[a[i]]++;
  36. }
  37.  
  38. } else {
  39. for (int i=x; i<=y; i++) {
  40. res += ((cnt[a[i]]<<)+)*a[i];
  41. cnt[a[i]]++;
  42. }
  43. }
  44. L = x, R = y;
  45. }
  46. int main() {
  47. int n, t;
  48.  
  49. scanf("%d%d", &n, &t);
  50. for (int i=; i<=n; i++) scanf("%I64d", &a[i]);
  51. int block_size = sqrt(n);
  52.  
  53. for (int i=; i<t; i++) {
  54. scanf("%d%d", &q[i].x, &q[i].y);
  55. q[i].l = q[i].x / block_size;
  56. q[i].p = i;
  57. }
  58.  
  59. sort(q, q+t, cmp);
  60.  
  61. memset(cnt, , sizeof(cnt));
  62.  
  63. res = ;
  64. for (int i=; i<t; i++) {
  65. query(q[i].x, q[i].y, i);
  66. ans[q[i].p] = res;
  67. }
  68.  
  69. for (int i=; i<t; i++) printf("%I64d\n", ans[i]);
  70.  
  71. return ;
  72. }

CF 86D Powerful array的更多相关文章

  1. CF 86D Powerful array 【分块算法,n*sqrt(n)】

    给定一个数列:A1, A2,……,An,定义Ks为区间(l,r)中s出现的次数. t个查询,每个查询l,r,对区间内所有a[i],求sigma(K^2*a[i]) 离线+分块 将n个数分成sqrt(n ...

  2. [置顶] CF 86D Powerful array 分块算法入门,n*sqrt(n)

    简介:分块算法主要是把区间划分成sqrt(n)块,从而降低暴力的复杂度, 其实这算是一种优化的暴力吧,复杂度O(n*sqrt(n)) 题意:给定一个数列:a[i]    (1<= i <= ...

  3. CodeForces 86D Powerful array(莫队+优化)

    D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input standard i ...

  4. Codeforces 86D Powerful array (莫队算法)

    题目链接 Powerful array 给你n个数,m次询问,Ks为区间内s的数目,求区间[L,R]之间所有Ks*Ks*s的和. $1<=n,m<=200000,   1<=s< ...

  5. Codeforces 86D Powerful array (莫队)

    D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input standard i ...

  6. codeforces 86D : Powerful array

    Description An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary su ...

  7. Codeforces#86D Powerful array(分块暴力)

    Description An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary su ...

  8. Codeforces 86D Powerful array(莫队算法)

    和BZOJ2038差不多..复习一下. #include<cstdio> #include<cmath> #include<algorithm> using nam ...

  9. Codeforces 86D - Powerful array(莫队算法)

    题目链接:http://codeforces.com/problemset/problem/86/D 题目大意:给定一个数组,每次询问一个区间[l,r],设cnt[i]为数字i在该区间内的出现次数,求 ...

随机推荐

  1. SAP存货账龄分析之库存获取

    前段时间上面要求做一个历史库存账龄分析,取历史数据的时候一直纠结于用mchb/mchbh/mska/mskah等实时和历史库存表,然而试来试去还是不能成功,于是决定DEBUG下MB5B的源代码,测试了 ...

  2. 麦子学院Android开发Java教程ClassCastException 错误解析

    现在Java编程中经常碰到ClassCastException 错误,ClassCastException 是 JVM 在检测到两个类型间的转换不兼容时引发的运行时异常.此类错误通常会终止用户请求.本 ...

  3. JS判断客户端是手机还是PC

    function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", " ...

  4. adb连接不上手机

    昨天电脑重装了系统,今天打开之前的eclips工作环境,点击run as -> android application,一直报各种诡异的错误,总之就是连接不上手机. 其中包括 Adb conne ...

  5. Golang container/ring闭环数据结构的使用方法

    //引入包 import "container/ring" //创建闭环,这里创建10个元素的闭环 r := ring.New(10) //给闭环中的元素附值 for i := 1 ...

  6. 如何去掉html中的超链接

    $a= preg_replace("/<a[^>]+>/", "", $a); $a= preg_replace("/<\/a ...

  7. openerp - asterisk connector(转载)

    原文:http://www.akretion.com/open-source-contributions/openerp-asterisk-voip-connector OpenERP - Aster ...

  8. VS2010调试入门指南

    1 导言 在软件开发周期中,测试和修正缺陷(defect,defect与bug的区别:Bug是缺陷的一种表现形式,而一个缺陷是可以引起多种Bug的)的时间远多于写代码的时间.通常,debug是指发现缺 ...

  9. java使用.net的webservice

    1.下载最新的axis2 http://mirrors.hust.edu.cn/apache//axis/axis2/java/core/1.6.3/axis2-1.6.3-bin.zip 2.解压使 ...

  10. DB天气app冲刺二阶段第六天

    今天干了一件让我有点小激动的事情 就是我感觉我貌似找到了为什么我的项目会闪退了有的时候..但是还不确定.等会会再试试看看到底对不对.好吧其实今天就干了这些事整整一下午调试,找bug,决定从头开始一点一 ...