zoukankan      html  css  js  c++  java
  • (莫队算法)两题莫队算法统计数量的入门题

    因为这两题差不多,而且比较简单,就放一起,做了这题,这种题目就是巨水的题了。随便写都行。

    CodeForces - 86D  Powerful array

    题意:

    多次查询数列中从L到R每个数字出现次数的平方乘这个数字的和。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <cmath>
     5 #include <map>
     6 #include <vector>
     7 #include <algorithm>
     8 
     9 using namespace std;
    10 
    11 const int maxn = 200010;
    12 const int bk = 350;
    13 int n, q;
    14 int a[maxn];
    15 struct Query {
    16     int l, r, index;
    17 };
    18 int cnt[maxn * 5];
    19 
    20 Query query[maxn];
    21 
    22 bool cmp(Query a, Query b) {
    23     if(a.l / bk == b.l / bk)return a.r < b.r;
    24     else return a.l / bk < b.l / bk;
    25 }
    26 
    27 long long ans[maxn];
    28 long long res = 0;
    29 
    30 void add(int x) {
    31     res += x * (2 * cnt[x] + 1);
    32     cnt[x]++;
    33 }
    34 
    35 void del(int x) {
    36     cnt[x]--;
    37     res -= x * (2 * cnt[x] + 1);
    38 }
    39 
    40 int main() {
    41     scanf("%d", &n);
    42     scanf("%d", &q);
    43     for(int i = 1; i <= n; i++) {
    44         scanf("%d", &a[i]);
    45     }
    46     for(int i = 0; i < q; i++) {
    47         scanf("%d%d", &query[i].l, &query[i].r);
    48         query[i].index = i;
    49     }
    50     sort(query, query + q, cmp);
    51     int left = 1, right = 0;
    52     for(int i = 0; i < q; i++) {
    53         if(right < query[i].r) {
    54             for(int j = right + 1; j <= query[i].r; j++) {
    55                 add(a[j]);
    56             }
    57         } else {
    58             for(int j = right; j > query[i].r; j--) {
    59                 del(a[j]);
    60             }
    61         }
    62         right = query[i].r;
    63         if(left < query[i].l) {
    64             for(int j = left; j < query[i].l; j++) {
    65                 del(a[j]);
    66             }
    67 
    68         } else {
    69             for(int j = left - 1; j >= query[i].l; j--) {
    70                 add(a[j]);
    71             }
    72         }
    73         left = query[i].l;
    74         ans[query[i].index] = res;
    75     }
    76     for(int i = 0; i < q; i++) {
    77         printf("%lld
    ", ans[i]);
    78 
    79     }
    80 
    81     return 0;
    82 }
    View Code

    NBUT - 1457 Sona

    题意:

    多次查询数列中L到R买个数字出现次数的立方和。

    特别注意:

    注意复杂度,因为数值较大,如果用map加个log的复杂度,可能会超时,而这个OJ没有开C++11,无法使用unordered_map,所以一定要先离散化。

    毕竟因为答案只跟次数有关跟值无关,所以无影响。

    代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <cmath>
      5 #include <map>
      6 #include <vector>
      7 #include <algorithm>
      8 
      9 using namespace std;
     10 
     11 inline bool scan_d(int &num) {
     12     char in;
     13     bool IsN = false;
     14     in = getchar();
     15     if(in == EOF) return false;
     16     while(in != '-' && (in < '0' || in > '9')) in = getchar();
     17     if(in == '-') {
     18         IsN = true;
     19         num = 0;
     20     } else num = in - '0';
     21     while(in = getchar(), in >= '0' && in <= '9') {
     22         num *= 10, num += in - '0';
     23     }
     24     if(IsN) num = -num;
     25     return true;
     26 }
     27 
     28 
     29 const int maxn = 100010;
     30 const int bk = 400;
     31 int n, q;
     32 int a[maxn];
     33 int b[maxn];
     34 struct Query {
     35     int l, r, index;
     36 };
     37 int cnt[maxn];
     38 
     39 Query query[maxn];
     40 
     41 bool cmp(Query a, Query b) {
     42     if(a.l / bk == b.l / bk)return a.r < b.r;
     43     else return a.l / bk < b.l / bk;
     44 }
     45 
     46 long long ans[maxn];
     47 long long res = 0;
     48 
     49 void add(int x) {
     50     res += 3 * cnt[x] * cnt[x] + 3 * cnt[x] + 1;
     51     cnt[x]++;
     52 }
     53 
     54 void del(int x) {
     55     cnt[x]--;
     56     res -= 3 * cnt[x] * cnt[x] + 3 * cnt[x] + 1;
     57 }
     58 
     59 
     60 void init() {
     61     sort(b + 1, b + n + 1);
     62     int pp = unique(b + 1, b + n + 1) - b;
     63     for(int i = 1; i <= n; i++) {
     64         a[i] = lower_bound(b + 1, b + pp + 1, a[i]) - b;
     65     }
     66 }
     67 
     68 int main() {
     69     while(scan_d(n)) {
     70         memset(cnt, 0, sizeof cnt);
     71         res = 0;
     72         for(int i = 1; i <= n; i++) {
     73             scan_d(a[i]);
     74             b[i] = a[i];
     75         }
     76         init();
     77         scan_d(q);
     78         for(int i = 0; i < q; i++) {
     79             scan_d(query[i].l);
     80             scan_d(query[i].r);
     81             query[i].index = i;
     82         }
     83         sort(query, query + q, cmp);
     84         int left = 1, right = 0;
     85         for(int i = 0; i < q; i++) {
     86             if(right < query[i].r) {
     87                 for(int j = right + 1; j <= query[i].r; j++) {
     88                     add(a[j]);
     89                 }
     90             } else {
     91                 for(int j = right; j > query[i].r; j--) {
     92                     del(a[j]);
     93                 }
     94             }
     95             right = query[i].r;
     96             if(left < query[i].l) {
     97                 for(int j = left; j < query[i].l; j++) {
     98                     del(a[j]);
     99                 }
    100 
    101             } else {
    102                 for(int j = left - 1; j >= query[i].l; j--) {
    103                     add(a[j]);
    104                 }
    105             }
    106             left = query[i].l;
    107             ans[query[i].index] = res;
    108         }
    109         for(int i = 0; i < q; i++) {
    110             printf("%I64d
    ", ans[i]);
    111         }
    112     }
    113 
    114     return 0;
    115 }
    View Code
  • 相关阅读:
    Dockerfile编写语法
    java应用测试报告生成(二):利用ant的build.xml生成测试报告
    java应用测试报告生成(一): sonarqube配合Jenkins生成测试报告及覆盖率
    cannot create windows service for mysql
    线程交互:生产消费模型
    线程同步与锁
    线程的五种状态及改变状态的三种方法
    简单的git入门介绍及常用操作
    CentOS/RHEL 7中的firewall控制
    oracle数据库兼容mysql的差异写法
  • 原文地址:https://www.cnblogs.com/tak-fate/p/7143656.html
Copyright © 2011-2022 走看看