luogu P2617 Dynamic Rankings(分块,n <= 1e4)

嘟嘟嘟

带修改区间第k大。

然而某谷把数据扩大到了1e5,所以用分块现在只能得50分。

分块怎么做呢?很暴力的。

基本思想还是块内有序,块外暴力统计。

对于修改,直接重排修改的数所在块,时间复杂度O(√nlogn√n)。

对于询问,二分答案,然后在每个块内再二分统计小于mid的数有几个,块外暴力统计,时间复杂度O(m * log1e9 * √nlog√n),所以只能过1e4。

  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 = 1e5 + 5;
 21 const int maxb = 320;
 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 << 1) + (ans << 3) + 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];
 43 void init()
 44 {
 45   S = sqrt(n);
 46   Cnt = n % S ? n / S + 1: n / S;
 47   for(rg int i = 1; i <= Cnt; ++i) lb[i] = rb[i - 1] + 1, rb[i] = lb[i] + S - 1;
 48   rb[Cnt] = n;
 49   for(rg int i = 1, j = 1; i <= n; ++i) blo[i] = j, j += (i == rb[j]);
 50   for(rg int i = 1, cb = 0; i <= Cnt; ++i, cb = 0)
 51     {
 52       for(rg 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 inline void update(const int& x, const int& k)
 57 {
 58   a[x] = k;
 59   int t = blo[x], cb = 0;
 60   for(rg int i = lb[t]; i <= rb[t]; ++i) b[t][++cb] = a[i];
 61   sort(b[t] + 1, b[t] + cb + 1);
 62 }
 63 inline int judge(const int& L, const int& R, const int& x, const int& k)
 64 {
 65   int l = blo[L], r = blo[R], ret = 0;
 66   if(l == r)
 67     {
 68       for(rg int i = L; i <= R; ++i) ret += (a[i] < x);
 69       return ret < k;
 70     }
 71   for(rg int i = l + 1; i < r; ++i)
 72     {
 73       int tp = lower_bound(b[i] + 1, b[i] + rb[i] - lb[i] + 2, x) - b[i] - 1;
 74       if(tp < 1) tp = 0;
 75       if(tp > rb[i] - lb[i]) tp = rb[i] - lb[i] + 1;
 76       ret += tp;
 77     }
 78   for(rg int i = L; i <= rb[l]; ++i) ret += (a[i] < x);
 79   for(rg int i = lb[r]; i <= R; ++i) ret += (a[i] < x);
 80   return ret < k;
 81 }
 82 
 83 int main()
 84 {
 85   n = read(), q = read();
 86   for(rg int i = 1; i <= n; ++i) a[i] = read();
 87   init();
 88   for(rg int i = 1; i <= q; ++i)
 89     {
 90       scanf("%s", c);
 91       if(c[0] == 'C')
 92     {
 93       int x = read(), y = read();
 94       update(x, y);
 95     }
 96       else
 97     {
 98       int L = read(), R = read(), k = read();
 99       int l = 0, r = 1e9;
100       while(l < r)
101         {
102           int mid = (l + r + 1) >> 1;
103           if(judge(L, R, mid, k)) l = mid;
104           else r = mid - 1;
105         }
106       write(l), enter;
107     }
108     }
109   return 0;
110 }
View Code
原文地址:https://www.cnblogs.com/mrclr/p/9870719.html