zoukankan      html  css  js  c++  java
  • 【BZOJ2653】【主席树+二分】middle

    Description

      一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。
      给你一个长度为n的序列s。
      回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
      其中a<b<c<d。
      位置也从0开始标号。
      我会使用一些方式强制你在线。

    Input

      第一行序列长度n。
      接下来n行按顺序给出a中的数。
      接下来一行Q。
      然后Q行每行a,b,c,d,我们令上个询问的答案是x(如果这是第一个询问则x=0)。
      令数组q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。
      将q从小到大排序之后,令真正的要询问的a=q[0],b=q[1],c=q[2],d=q[3]。
      输入保证满足条件。

    Output

      Q行依次给出询问的答案。

    Sample Input

    5
    170337785
    271451044
    22430280
    969056313
    206452321
    3
    3 1 0 2
    2 3 1 4
    3 1 4 0

    271451044
    271451044
    969056313

    Sample Output

    Hint

      0:n,Q<=100

      1,...,5:n<=2000

      0,...,19:n<=20000,Q<=25000

    Source

    【分析】

    居然wa了一下TAT.

    比较简单的题目,按照权值大小初始化一下线段树将其可持久化,对于二分的版本求前缀和的最大最小值减一下看是否大于等于0就可以了。

      1 /*
      2 唐代贾岛
      3 《剑客 / 述剑》
      4 十年磨一剑,霜刃未曾试。
      5 今日把示君,谁有不平事? 
      6 */
      7 #include <iostream>
      8 #include <cstdio>
      9 #include <algorithm>
     10 #include <cstring>
     11 #include <vector>
     12 #include <utility>
     13 #include <iomanip>
     14 #include <string>
     15 #include <cmath>
     16 #include <queue>
     17 #include <assert.h>
     18 #include <map>
     19 #include <ctime>
     20 #include <cstdlib>
     21 #include <stack>
     22 #define LOCAL
     23 const int INF = 0x7fffffff;
     24 const int MAXN = 20000  + 10;
     25 const int maxnode = 20000 * 2 + 200000 * 20;
     26 const int maxm= 30000 * 2 + 10;
     27 using namespace std;
     28 struct DATA{
     29        int num;
     30        int order;
     31        bool operator < (const DATA &b)const{
     32             return num < b.num;
     33        }
     34 }sorted[MAXN];
     35 int data[MAXN];
     36 struct Node{
     37        int l, r;
     38        int Max, val, sum, Min; 
     39        Node *ch[2];
     40 }*root[MAXN], mem[maxnode];
     41 int tot, n;
     42 
     43 Node *NEW(int l, int r){
     44      Node *p = &mem[tot++];
     45      p->l = l;
     46      p->r = r;
     47      p->val = p->sum = p->Max = p->Min = 1;
     48      p->ch[0] = p->ch[1] = NULL;
     49      return p;
     50 }
     51 void update(Node *&t){
     52      if (t->l == t->r) return;
     53      t->sum = 0;
     54      if (t->ch[0] != NULL) t->sum += t->ch[0]->sum;
     55      if (t->ch[1] != NULL) t->sum += t->ch[1]->sum;
     56      
     57      t->Max = max(t->ch[1]->Max + t->ch[0]->sum, t->ch[0]->Max);
     58      t->Min = min(t->ch[1]->Min + t->ch[0]->sum, t->ch[0]->Min);
     59      return;
     60 }
     61 void build(Node *&t, int l, int r){
     62      if (t == NULL){
     63         t = NEW(l, r);
     64      }
     65      if (l == r) return;
     66      int mid = (l + r) >> 1;
     67      build(t->ch[0], l, mid);
     68      build(t->ch[1], mid + 1, r);
     69      update(t);
     70 }
     71 //将l改为-1 
     72 void change(Node *&t, Node *&last, int l){
     73      if (t == NULL){
     74            t = NEW(last->l, last->r);
     75            t->val = last->val;
     76            t->Max = last->Max;
     77            t->Min = last->Min;
     78            t->sum = last->sum;
     79      }
     80      if (t->l == l && t->r == l){
     81         t->Min = t->Max = t->sum = -1;
     82         return;
     83      }
     84      int mid = (t->l + t->r) >> 1;
     85      if (l <= mid){
     86         change(t->ch[0], last->ch[0], l);
     87         t->ch[1] = last->ch[1];
     88      }else{
     89         change(t->ch[1], last->ch[1], l);
     90         t->ch[0] = last->ch[0];
     91      }
     92      update(t);
     93 }
     94 int qSum(Node *t, int l, int r){
     95     if (l > r) return 0;
     96     if (l == 0) return qSum(t, l + 1, r);
     97     
     98     if (l <= t->l && t->r <= r) return t->sum;
     99     int mid = (t->l + t->r) >>1;
    100     int sum = 0;
    101     if (l <= mid) sum += qSum(t->ch[0], l, r);
    102     if (r > mid) sum += qSum(t->ch[1], l, r);
    103     return sum;
    104 }
    105 int qMax(Node *t, int l, int r, int k){
    106      if (l == 0) return max(0, qMax(t, l + 1, r, k));
    107      
    108      if (l <= t->l && t->r <= r) return t->Max + qSum(root[k], 1, t->l - 1);
    109      int mid = (t->l + t->r) >> 1;
    110      int Ans = -INF;
    111      if (l <= mid) Ans = max(Ans, qMax(t->ch[0], l, r, k));
    112      if (r > mid) Ans = max(Ans, qMax(t->ch[1], l, r, k));
    113      return Ans;
    114 }
    115 int qMin(Node *t, int l, int r, int k){
    116      if (l == 0) return min(0, qMin(t, l + 1, r, k));
    117      
    118      if (l <= t->l && t->r <= r) return t->Min + qSum(root[k], 1, t->l - 1);
    119      int mid = (t->l + t->r) >> 1;
    120      int Ans = INF;
    121      if (l <= mid) Ans = min(Ans, qMin(t->ch[0], l, r, k));
    122      if (r > mid) Ans = min(Ans, qMin(t->ch[1], l, r, k));
    123      return Ans;
    124 }
    125 
    126 void init(){
    127      scanf("%d", &n);
    128      for (int i = 1; i <= n; i++){
    129          sorted[i].order = i;
    130          scanf("%d", &sorted[i].num);
    131          data[i] = sorted[i].num;
    132      }
    133      //离散化 
    134      sort(sorted + 1, sorted + 1 + n);
    135      
    136      tot = 0;
    137      root[1] = NULL;
    138      build(root[1], 1, n);
    139      //开始可持久化 
    140      for (int i = 2; i <= (n + 1); i++) change(root[i], root[i - 1], sorted[i - 1].order); 
    141      //printf("%d", root[6]->Max);
    142      /*int cnt = 0;
    143      for (int i = 1; i <= n; i++){
    144          if (i == 0 || sorted[i].num != sorted[i - 1].num) cnt++;
    145          rem[cnt] = sorted[i].num;
    146          data[sorted[i].order] = cnt;
    147      }*/
    148      //for (int i = 1; i <= n; i++)
    149 } 
    150 int search(int a, int b, int c, int d){
    151     int Ans, l = 1, r = n;
    152     while (l <= r){
    153           int mid = (l + r) >> 1;
    154           if ((qMax(root[mid], c, d, mid) - qMin(root[mid], a, b, mid)) >= 0) Ans = mid, l = mid + 1;
    155           else r = mid - 1; 
    156     }
    157     return Ans;
    158 }
    159 void work(){
    160      int last_ans = 0, m;
    161      scanf("%d", &m);
    162      for (int i = 1; i <= m; i++){
    163          int q[5];
    164          for (int j = 1; j <= 4; j++){
    165              scanf("%d", &q[j]); 
    166              q[j] = (q[j] + last_ans) % n;
    167          }
    168          sort(q + 1, q + 1 + 4);
    169          int a = q[1], b = q[2], c = q[3], d = q[4];
    170          a++;c++;
    171          b++;d++;
    172          //printf("%d", qMax(root[5], 3, 3, 5));
    173          //printf("%d%d%d%d
    ", a, b, c, d);
    174          last_ans = sorted[search(a - 1, b - 1, c, d)].num;
    175          printf("%d
    ", last_ans);
    176      } 
    177 }
    178 
    179 int main (){
    180     
    181     init();
    182     work();
    183     return 0;
    184 }
    View Code
  • 相关阅读:
    jenkins+robot_framework的安装与邮件配置
    kali最新版中文乱码破解
    Kali系统安装详细步骤
    ADK安装步骤
    Newman跑接口脚本
    Android手机APP测试之环境搭建
    pytest+allre框架搭建
    Android手机测试环境搭建
    adb电脑桥梁手机步骤以及操作
    Android SDK的安装与环境变量配置
  • 原文地址:https://www.cnblogs.com/hoskey/p/4343530.html
Copyright © 2011-2022 走看看