zoukankan      html  css  js  c++  java
  • 【CodeForces】86D Powerful array

    题意:

    给出一个数列1~n。

    令ks表示s的出现次数。

    询问区间[x,y]中,s * ks^2之和。

    将数列分成sqrt(n)块,不在区间范围内的暴力,但是在区间范围内的无法常数时间统计。

    以下算法及证明摘自CodeForces...

    Let's sort the query intervals according to the following rule: first come the intervals with the left ends in Q_1, then the intervals with the left ends in Q_2, and so on. And if the left ends of the two queries belong to the same part, then the interval with the more left right end is assumed to be smaller.
    In order to prove the stated asymptotic behavior we will follow the steps of the left and the right ends independently. We note that the left ends that belong to the same Q_i make <= n / p steps, and transition to Q_{i+1} costs no more than 2 * n / p steps. Therefore the left ends make <= n/p * n + 2*n steps (the second summand is O(n), and it's negligible).
    The right ends in the common group move only to the right, and this proves <= n * p steps (during the whole process) estimate. We will estimate the transition to the next Q_i at no more than n steps, so overall we get <= 2 * n * p steps.
    Thus, the total number of steps is no more than (n / p * n + 2 * n * p). Now we choose p = sqrt(n) which proves the statement.

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define MAXN 200010
     6 #define EPS 1e-8
     7 typedef long long LL;
     8 using namespace std;
     9 LL res, ans[MAXN];
    10 int n, block, L, R;
    11 int cnt[MAXN * 5], a[MAXN];
    12 struct node {
    13     int x, y, left, pos;
    14 };
    15 node p[MAXN];
    16 inline bool cmp(node a, node b) {
    17     if (a.left == b.left)
    18         return a.y < b.y;
    19     return a.left < b.left;
    20 }
    21 void Query(int x, int y, int flag) {
    22     int i;
    23     if (flag) {
    24         for (i = L - 1; i >= x; i--) {
    25             cnt[a[i]]++;
    26             res += ((cnt[a[i]] << 1) - 1) * (LL) a[i];
    27         }
    28         for (i = L; i < x; i++) {
    29             res -= ((cnt[a[i]] << 1) - 1) * (LL) a[i];
    30             cnt[a[i]]--;
    31         }
    32         for (i = R + 1; i <= y; i++) {
    33             cnt[a[i]]++;
    34             res += ((cnt[a[i]] << 1) - 1) * (LL) a[i];
    35         }
    36         for (i = R; i > y; i--) {
    37             res -= ((cnt[a[i]] << 1) - 1) * (LL) a[i];
    38             cnt[a[i]]--;
    39         }
    40     } else {
    41         for (i = x; i <= y; i++) {
    42             cnt[a[i]]++;
    43             res += ((cnt[a[i]] << 1) - 1) * (LL) a[i];
    44         }
    45     }
    46     L = x;
    47     R = y;
    48 }
    49 int main() {
    50     int q, i;
    51     while (~scanf("%d%d", &n, &q)) {
    52         memset(cnt, 0, sizeof(cnt));
    53         block = (int) (ceil(sqrt((double) n)) + EPS);
    54         for (i = 1; i <= n; i++)
    55             scanf("%d", &a[i]);
    56         for (i = 0; i < q; i++) {
    57             scanf("%d%d", &p[i].x, &p[i].y);
    58             p[i].left = p[i].x / block;
    59             p[i].pos = i;
    60         }
    61         sort(p, p + q, cmp);
    62         for (res = i = 0; i < q; i++) {
    63             Query(p[i].x, p[i].y, i);
    64             ans[p[i].pos] = res;
    65         }
    66         for (i = 0; i < q; i++)
    67             printf("%I64d\n", ans[i]);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    Push&Pop压栈出栈(你知道栈里存了什么东西吗?)
    为啥不管什么错误系统总会进HardFault_Handler(),看完这篇文章你就明白!
    MLX90620红外矩阵传感器驱动(基于传感器管理组件)
    APDS-9960手势检测、接近检测、数字环境光感(ALS)和色感(RGBC)传感器驱动(基于传感器管理组件)
    DHT11数字温度湿度传感器驱动(基于传感器管理组件)
    es6的一些新特性(1)
    js let var const区别
    vue的双向数据绑定原理
    BFC的概念及作用
    JS多重判断 / ES6 includes
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2660839.html
Copyright © 2011-2022 走看看