zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    三地气温的典型相关分析
    android 使用 BroadcastReceiver 总结
    发布网站问题笔记
    Android 两个Activity 实现数据的来回传递
    input 标签屏蔽谷歌浏览器高亮显示
    javascript 获取当前html 标签的位置
    c# 四舍五入
    利用SQL的charindex实现字符串数组和Split函数
    ExtJs 一些常用的控件
    C#中return、break、continue的用法
  • 原文地址:https://www.cnblogs.com/767355675hutaishi/p/4391008.html
Copyright © 2011-2022 走看看