• D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力


      莫队算法就是优化的暴力算法。莫队算法是要把询问先按左端点属于的块排序,再按右端点排序。只是预先知道了所有的询问。可以合理的组织计算每个询问的顺序以此来降低复杂度。

                              D. Powerful array

    典型的莫队算法题

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <string>
     7 #include <vector>
     8 #include <set>
     9 #include <map>
    10 #include <stack>
    11 #include <queue>
    12 #include <sstream>
    13 #include <iomanip>
    14 using namespace std;
    15 typedef long long LL;
    16 const int INF=0x4fffffff;
    17 const int EXP=1e-5;
    18 const int MS=200005;
    19 
    20 int a[MS];
    21 int cnt[5*MS];
    22 LL ans[MS];
    23 
    24 struct node
    25 {
    26     int l,r;
    27     int no,qid;
    28     bool operator <(const node &a)const
    29     {
    30             return no<a.no||(no==a.no&&r<a.r);
    31     }
    32 }nodes[MS];
    33 
    34 
    35 int n,SIZE;
    36 LL res;
    37 int L,R;
    38 LL query(int x,int y,int flag)
    39 {
    40     if(flag)
    41     {
    42         for(int i=x;i<L;i++)
    43         {
    44             res+=(cnt[a[i]]<<1|1)*a[i];
    45             cnt[a[i]]++;
    46         }
    47         for(int i=L;i<x;i++)
    48         {
    49             cnt[a[i]]--;
    50             res-=(cnt[a[i]]<<1|1)*a[i];
    51         }
    52         for(int i=R+1;i<=y;i++)
    53         {
    54             res+=(cnt[a[i]]<<1|1)*a[i];
    55             cnt[a[i]]++;
    56         }
    57         for(int i=y+1;i<=R;i++)
    58         {
    59             cnt[a[i]]--;
    60             res-=(cnt[a[i]]<<1|1)*a[i];
    61         }
    62     }
    63     else
    64     {
    65         for(int i=x;i<=y;i++)
    66         {
    67             res+=(cnt[a[i]]<<1|1)*a[i];
    68             cnt[a[i]]++;
    69         }
    70     }
    71     L=x;R=y;
    72     return res;
    73 }
    74 
    75 int main()
    76 {
    77     int Q;
    78     scanf("%d%d",&n,&Q);
    79     for(int i=1;i<=n;i++)
    80     {
    81         scanf("%d",&a[i]);               //   注意%d的速度远大于%I64d的速度
    82                                                    //   在大量数据输入时,能用%d就不要用%I64d,但千万要注意数据溢出
    83     }
    84     SIZE=sqrt(n+0.5);
    85     for(int i=0;i<Q;i++)
    86     {
    87         scanf("%d%d",&nodes[i].l,&nodes[i].r);
    88         nodes[i].no=nodes[i].l/SIZE;
    89         nodes[i].qid=i;
    90     }
    91     sort(nodes,nodes+Q);
    92     memset(cnt,0,sizeof(cnt));
    93     res=0;
    94     for(int i=0;i<Q;i++)
    95         ans[nodes[i].qid]=query(nodes[i].l,nodes[i].r,i);
    96     for(int i=0;i<Q;i++)
    97         printf("%I64d
    ",ans[i]);
    98     return 0;
    99 }
  • 相关阅读:
    【LOJ #2290】「THUWC 2017」随机二分图(状压DP)
    【LOJ #2136】「ZJOI2015」地震后的幻想乡(状压DP)
    【CSP-S 2019模拟】题解
    异步编程补漏
    Git(七) 查漏补缺
    ES6(二) let const
    ES6(一) 数组
    JS判断对象是否存在
    Git(六)
    Git(五)
  • 原文地址:https://www.cnblogs.com/767355675hutaishi/p/4391008.html
Copyright © 2020-2023  润新知