zoukankan      html  css  js  c++  java
  • LGP2801 教主的魔法

    题目链接 : P2801 教主的魔法

    这是第一次A分块的题

    就是模板题了

    每个块内排序 每个整块仅需维护整块的修改量 

    询问操作:

    对于边缘块 直接暴力找在[l, r]内 且比给定值大的有几个

    对于整块 二分查找不小于 (给定值 - 本块修改量) 的块有多少个

    修改操作:

    边缘块直接修改

    整块在修改量标记上修改

    本题细节较多 尤其是修改和询问的范围

    【明明是蒟蒻不熟练。。。

    附上代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cmath>
     4 using namespace std;
     5 const int N = 1e6 + 5;
     6 struct Node{
     7     int bl, id;
     8     long long x;
     9 }node[N]; 
    10 int n, blo, q, ts;
    11 long long atag[N];//修改量标记
    12  
    13 bool rule1(Node a, Node b){
    14     return a.x < b.x;
    15 }
    16 //把[a, b]的元素加c
    17 void add(int a, int b, long long c){
    18     for(int i = (node[a].bl - 1) * blo + 1; i <= min(b, min(n, node[a].bl * blo)); i++)
    19         if(node[i].id >= a)
    20             node[i].x += c;
    21     sort(node + (node[a].bl - 1) * blo + 1, node + min(n, node[a].bl * blo) + 1, rule1);
    22     if(node[a].bl != node[b].bl)
    23         for(int i = (node[b].bl - 1) * blo + 1; i <= min(n, node[b].bl * blo); i++)
    24             if(node[i].id <= b)
    25                 node[i].x += c;
    26     sort(node + (node[b].bl - 1) * blo + 1, node + min(n, node[b].bl * blo) + 1, rule1);
    27     for(int i = node[a].bl + 1; i <= node[b].bl - 1; i++)
    28         atag[i] += c;    
    29 }
    30 //二分查找pos块中比a大的元素个数
    31 int find(int pos, long long a){
    32     if(a > node[min(n, pos * blo)].x) return 0;
    33     int l = (pos - 1) * blo + 1, r = min(n, pos * blo), mid;
    34     while(l < r){
    35         mid = l + ((r - l) >> 1);
    36         if(node[mid].x >= a) r = mid;
    37         else l = mid + 1;
    38     }
    39     return min(n, pos * blo) - l + 1;
    40 }
    41 //询问 [a, b]中大于等于c的元素个数
    42 int query(int a, int b, long long c){
    43     int ans = 0;
    44     for(int i = (node[a].bl - 1) * blo + 1; i <= min(b, min(n, node[a].bl * blo)); i++)
    45         if(node[i].id >= a && node[i].x >= c - atag[node[a].bl]) 
    46             ans++; 
    47 
    48     if(node[a].bl != node[b].bl) 
    49         for(int i = (node[b].bl - 1) * blo + 1; i <= min(n, node[b].bl * blo); i++)
    50             if(node[i].id <= b && node[i].x >= c - atag[node[b].bl]) 
    51                 ans++;
    52 
    53     for(int i = node[a].bl + 1; i <= node[b].bl - 1; i++)
    54         ans += find(i, c - atag[i]);
    55     return ans;
    56 }
    57 
    58 int main(){
    59     scanf("%d%d", &n, &q);
    60     blo = sqrt(n);
    61     for(int i = 1; i <= n; i++) scanf("%d", &node[i].x);
    62 //输入
    63     for(int i = 1; i <= n; i++){
    64         node[i].bl = (i - 1) / blo + 1;
    65         node[i].id = i;
    66     }
    67     for(int i = 1; i <= node[n].bl; i++)
    68         sort(node + (i - 1) * blo + 1, node + min(n, i * blo) + 1, rule1);
    69 //块的分配与块内排序
    70     char op[10];
    71     int x, y, z;
    72     for(int i = 1; i <= q; i++){
    73         scanf("%s%d%d%d", op, &x, &y, &z);
    74         if(op[0] == 'M') add(x, y, z);
    75         else printf("%d
    ", query(x, y, z));
    76     }
    77     return 0;    
    78 }
    View Code
  • 相关阅读:
    HDU 1728 逃离迷宫
    程序猿求职之道(《程序猿面试笔试宝典》)之不想签约,但也不想轻易放弃机会,怎么办?
    职场生涯(—)
    Python学习笔记24:Django搭建简单的博客站点(二)
    &quot;高可用方案工具包&quot; high availability toolkit 1.1
    [Swift]LeetCode421. 数组中两个数的最大异或值 | Maximum XOR of Two Numbers in an Array
    [Swift]LeetCode420. 强密码检验器 | Strong Password Checker
    [Swift]LeetCode419. 甲板上的战舰 | Battleships in a Board
    [Swift]LeetCode417. 太平洋大西洋水流问题 | Pacific Atlantic Water Flow
    [Swift通天遁地]七、数据与安全-(11)如何检测应用程序中的内存泄露
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9431722.html
Copyright © 2011-2022 走看看