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
  • 相关阅读:
    组装query,query汇总,query字段
    POJ 1276, Cash Machine
    POJ 1129, Channel Allocation
    POJ 2531, Network Saboteur
    POJ 1837, Balance
    POJ 3278, Catch That Cow
    POJ 2676, Sudoku
    POJ 3126, Prime Path
    POJ 3414, Pots
    POJ 1426, Find The Multiple
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9431722.html
Copyright © 2011-2022 走看看