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 }
原文地址:https://www.cnblogs.com/767355675hutaishi/p/4391008.html