zoukankan      html  css  js  c++  java
  • luogu P2801 教主的魔法 分块

    分块算法通常能跟暴力相结合,从而在较为优秀的时间内解决一个常规方法难以解决的问题,很神奇。

    我们考虑将序列分块,每个块内按照身高排序。

    对于修改操作,我们对于左右的边界所在的块,排回原序后,暴力修改,再按照身高排回来。O(sqrt(n)logn)。对于中间的整块,打一个标记来修改。O(sqrt(n))。

    对于询问操作,我们对于左右的边界所在的快,排回原序后,暴力查询,再按照身高排回来。O(sqrt(n)logn)。对于中间的整块,因为每一块都有序,所以我们对于每一块二分查找下,多少个人身高不低于c,别忘记把标记算上,二分边界情况也处理好,被二分边界卡了一个点想了半天。O(sqrt(n)logn)。

    所以总的复杂度为O(q sqrt(n) logn),开完O2勉强跑过。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cmath>
      4 using namespace std;
      5 struct pot
      6 {
      7     int h,id;
      8 } vec[1001000];
      9 int add[1001000];
     10 int n,q,blk;
     11 bool cmp1(pot a,pot b)
     12 {
     13     return a.h < b.h;
     14 }
     15 bool cmp2(pot a,pot b)
     16 {
     17     return a.id < b.id;
     18 }
     19 void vec_add(int x,int y,int w)
     20 {
     21     int lbn = (x - 1) / blk + 1;
     22     int rbn = (y - 1) / blk + 1;
     23     int lbb = (lbn - 1) * blk + 1;
     24     int lbe = min(lbn * blk,n);
     25     int rbb = (rbn - 1) * blk + 1; 
     26     int rbe = min(rbn * blk,n);
     27     if (lbn == rbn)
     28     {
     29         sort(vec + lbb,vec + lbe + 1,cmp2);
     30         for (int i = x;i <= y;i++)
     31             vec[i].h += w;
     32         sort(vec + lbb,vec + lbe + 1,cmp1);
     33     }
     34     //
     35     sort(vec + lbb,vec + lbe + 1,cmp2);
     36     for (int i = x;i <= lbe;i++) 
     37         vec[i].h += w;
     38     sort(vec + lbb,vec + lbe + 1,cmp1);
     39     //
     40     sort(vec + rbb,vec + rbe + 1,cmp2);
     41     for (int i = rbb;i <= y;i++)
     42         vec[i].h += w;
     43     sort(vec + rbb,vec + rbe + 1,cmp1);
     44     //
     45     for (int i = lbn + 1;i <= rbn - 1;i++) 
     46         add[i] += w;
     47 }
     48 int vec_qry(int x,int y,int c)
     49 {
     50     int res = 0;
     51     int lbn = (x - 1) / blk + 1;
     52     int rbn = (y - 1) / blk + 1;
     53     int lbb = (lbn - 1) * blk + 1;
     54     int lbe = min(lbn * blk,n);
     55     int rbb = (rbn - 1) * blk + 1; 
     56     int rbe = min(rbn * blk,n);
     57     if (lbn == rbn)
     58     {
     59         sort(vec + lbb,vec + lbe + 1,cmp2);
     60         for (int i = x;i <= y;i++)
     61             res += vec[i].h + add[lbn] >= c ? 1 : 0;
     62         sort(vec + lbb,vec + lbe + 1,cmp1);
     63         return res;
     64     }
     65     //
     66     sort(vec + lbb,vec + lbe + 1,cmp2);
     67     for (int i = x;i <= lbe;i++) 
     68         res += vec[i].h + add[lbn] >= c ? 1 : 0;
     69     sort(vec + lbb,vec + lbe + 1,cmp1);
     70     //
     71     sort(vec + rbb,vec + rbe + 1,cmp2);
     72     for (int i = rbb;i <= y;i++)
     73         res += vec[i].h + add[rbn] >= c ? 1 : 0;
     74     sort(vec + rbb,vec + rbe + 1,cmp1);
     75     //
     76     for (int i = lbn + 1;i <= rbn - 1;i++) 
     77     {
     78         int l = (i - 1) * blk + 1,r = i * blk,mid;
     79         while (l < r)
     80         {
     81             mid = l + r >> 1;
     82             if (vec[mid].h + add[i] >= c)
     83                 r = mid;
     84             else
     85                 l = mid + 1; 
     86         }
     87         res += i * blk - l + 1;
     88         if (vec[l].h + add[i] < c) res--;
     89     }
     90     return res;
     91 }
     92 int main()
     93 {
     94     scanf("%d%d",&n,&q);
     95     blk = sqrt(n);
     96     for (int i = 1;i <= n;i++)
     97     {
     98         scanf("%d",&vec[i].h);
     99         vec[i].id = i;
    100     }
    101     for (int i = 1;i <= n;i += blk)
    102         sort(vec + i,vec + min(n,i + blk - 1) + 1,cmp1);
    103     int tx,ty,tw;
    104     char str[10];
    105     for (int i = 1;i <= q;i++)
    106     {
    107         scanf("%s%d%d%d",str,&tx,&ty,&tw);
    108         if (str[0] == 'M')
    109             vec_add(tx,ty,tw);
    110         else
    111             printf("%d
    ",vec_qry(tx,ty,tw));
    112     }
    113     return 0;
    114 }
    心之所动 且就随缘去吧
  • 相关阅读:
    [HTML5] document.hidden
    在vue页面中设置resize事件
    document之ES6解构
    vue中mixins的使用方法和注意点---mixins第二篇(异步请求的情况)
    vue中mixins的使用方法和注意点---mixins第一篇
    vue中路由重定向redirect
    如何理解dispatch( 'tagsView/delAllViews',null,{root:true} )里面的root:true
    vue计算属性computed中的get和set的使用
    splice(0)的奇妙用法
    4月5日学习日志
  • 原文地址:https://www.cnblogs.com/iat14/p/10519815.html
Copyright © 2011-2022 走看看