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

    嘟嘟嘟

    分块好题。

    想法其实特别暴力,对于每一个块,都在块内排一个序,这样查询整块的时候二分找大于等于k - add[i]的数有多少。然后块外零散的数就暴力判断好啦。

    所以有两个数组b[i][……]:代表第 i 块有哪些数;add[i]是整块加标记。

    然后修改的时候,对于零散的数所在块,暴力重构b数组。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 1e6 + 5;
     21 const int maxb = 1e3 + 5;
     22 inline ll read()
     23 {
     24   ll ans = 0;
     25   char ch = getchar(), last = ' ';
     26   while(!isdigit(ch)) {last = ch; ch = getchar();}
     27   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     28   if(last == '-') ans = -ans;
     29   return ans;
     30 }
     31 inline void write(ll x)
     32 {
     33   if(x < 0) x = -x, putchar('-');
     34   if(x >= 10) write(x / 10);
     35   putchar(x % 10 + '0');
     36 }
     37 
     38 int n, q, a[maxn];
     39 char c[2];
     40 
     41 int S, Cnt = 0, blo[maxn], lb[maxn], rb[maxn];
     42 int b[maxb][maxb], add[maxb];
     43 void init()
     44 {
     45   S = sqrt(n);
     46   Cnt = n % S ? n / S : n / S + 1;
     47   for(int i = 1; i <= Cnt; ++i) lb[i] = (i - 1) * S, rb[i] = i * S - 1;
     48   rb[Cnt] = n;
     49   for(int i = 1, j = 1; i <= n; ++i) blo[i] = j, j += (i == rb[j]);
     50   for(int i = 1, cb = 0; i <= Cnt; ++i, cb = 0)
     51     {
     52       for(int j = lb[i]; j <= rb[i]; ++j) b[i][++cb] = a[j];
     53       sort(b[i] + 1, b[i] + cb + 1);
     54     }
     55 }
     56 void update(int L, int R, int k)
     57 {
     58   int l = blo[L], r = blo[R], cb = 0;
     59   if(l == r)
     60     {
     61       for(int i = L; i <= R; ++i) a[i] += k;
     62       for(int i = lb[l]; i <= rb[l]; ++i) b[l][++cb] = a[i];
     63       sort(b[l] + 1, b[l] + cb + 1);
     64       return;
     65     }
     66   for(int i = l + 1; i < r; ++i) add[i] += k;
     67   for(int i = L; i <= rb[l]; ++i) a[i] += k;
     68   for(int i = lb[l]; i <= rb[l]; ++i) b[l][++cb] = a[i];
     69   sort(b[l] + 1, b[l] + cb + 1);
     70   cb = 0;
     71   for(int i = lb[r]; i <= R; ++i) a[i] += k;
     72   for(int i = lb[r]; i <= rb[r]; ++i) b[r][++cb] = a[i];
     73   sort(b[r] + 1, b[r] + cb + 1);
     74 }
     75 int query(int L, int R, int k)
     76 {
     77   int l = blo[L], r = blo[R], ret = 0;
     78   if(l == r)
     79     {
     80       for(int i = L; i <= R; ++i) ret += (a[i] + add[l] >= k);
     81       return ret;
     82     }
     83   for(int i = l + 1; i < r; ++i)
     84     {
     85       int tp = lower_bound(b[i] + 1, b[i] + rb[i] - lb[i] + 2, k - add[i]) - b[i];
     86       if(tp > rb[i] - lb[i] + 1) continue;
     87       ret += rb[i] - lb[i] + 1 - tp + 1;
     88     }
     89   for(int i = L; i <= rb[l]; ++i) ret += (a[i] + add[l] >= k);
     90   for(int i = lb[r]; i <= R; ++i) ret += (a[i] + add[l] >= k);
     91   return ret;
     92 }
     93 
     94 int main()
     95 {
     96   n = read(), q = read();
     97   for(int i = 1; i <= n; ++i) a[i] = read();
     98   init();
     99   for(int i = 1; i <= q; ++i)
    100     {
    101       scanf("%s", c);
    102       int L = read(), R = read(), k = read();
    103       if(c[0] == 'M') update(L, R, k);
    104       else write(query(L, R, k)), enter;
    105     }
    106   return 0;
    107 }
    View Code
  • 相关阅读:
    ndk学习17: jni之Java调用C&C++
    ndk学习18: JNI之C&C++调用Java
    ndk学习15: IPC机制
    正向代理和反向代理
    java内存泄露与内存溢出
    权限管理及shiro框架
    异构信息网络
    基于遗传算法的试题组卷
    Java JNI机制
    Lucene及全文搜索实现原理
  • 原文地址:https://www.cnblogs.com/mrclr/p/9868985.html
Copyright © 2011-2022 走看看