zoukankan      html  css  js  c++  java
  • BZOJ K大数查询(分治)(Zjoi2013)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3110

    Description

    有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
    如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

    Input

    第一行N,M
    接下来M行,每行形如1 a b c或2 a b c

    Output

    输出每个询问的结果

     
    题目大意:略。
    思路:分治答案。答案范围[-n, n],从前往后扫描,若是插入操作且c>mid,则把线段树中区间[a, b]加一,并置为为类别1;否则置为类别0。若是询问操作,若目前线段树中区间[a, b]的和小于等于c,则置为类别1;否则置为类别0,并把c减去区间[a, b]的和。然后分治处理,其中类别0中,答案范围为[-n, mid];类别1中,答案范围为[mid + 1, n]。按类别排序后,两个区间之间互不影响。时间复杂度为O(nlognlogn)。
     
    代码(4940MS):
      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 using namespace std;
      6 typedef long long LL;
      7 
      8 const int MAXN = 50010;
      9 const int MAXT = MAXN << 2;
     10 
     11 int sum[MAXT];
     12 int add[MAXT];
     13 bool clr[MAXT];
     14 
     15 #define ll (x << 1)
     16 #define rr (ll | 1)
     17 #define mid ((l + r) >> 1)
     18 void initTree() {
     19     sum[1] = add[1] = 0;
     20     clr[1] = true;
     21 }
     22 
     23 void pushdown(int x, int l, int r) {
     24     if(clr[x]) {
     25         clr[ll] = clr[rr] = true;
     26         sum[ll] = sum[rr] = add[ll] = add[rr] = 0;
     27         clr[x] = false;
     28     }
     29     if(add[x]) {
     30         sum[ll] += (mid - l + 1) * add[x];
     31         add[ll] += add[x];
     32         sum[rr] += (r - mid) * add[x];
     33         add[rr] += add[x];
     34         add[x] = 0;
     35     }
     36 }
     37 
     38 void maintain(int x) {
     39     sum[x] = sum[ll] + sum[rr];
     40 }
     41 
     42 void modify(int x, int l, int r, int a, int b) {
     43     if(a <= l && r <= b) {
     44         add[x]++;
     45         sum[x] += (r - l + 1);
     46     } else {
     47         pushdown(x, l, r);
     48         if(a <= mid) modify(ll, l, mid, a, b);
     49         if(mid < b) modify(rr, mid + 1, r, a, b);
     50         maintain(x);
     51     }
     52 }
     53 
     54 int query(int x, int l, int r, int a, int b) {
     55     if(a <= l && r <= b) {
     56         return sum[x];
     57     } else {
     58         pushdown(x, l, r);
     59         int res = 0;
     60         if(a <= mid) res += query(ll, l, mid, a, b);
     61         if(mid < b) res += query(rr, mid + 1, r, a, b);
     62         return res;
     63     }
     64 }
     65 #undef mid
     66 
     67 struct Node {
     68     int op, id, a, b, c, v;
     69     void read(int i) {
     70         id = i;
     71         scanf("%d%d%d%d", &op, &a, &b, &c);
     72     }
     73     bool operator < (const Node &rhs) const {
     74         if(v != rhs.v) return v < rhs.v;
     75         return id < rhs.id;
     76     }
     77 } p[MAXN];
     78 int ans[MAXN];
     79 int n, m;
     80 
     81 void work(int a, int b, int l, int r) {
     82     if(l > r) return ;
     83     if(a == b) {
     84         for(int i = l; i <= r; ++i)
     85             if(p[i].op == 2) ans[p[i].id] = a;
     86         return ;
     87     }
     88     initTree();
     89     int mid = a + ((b - a) >> 1), t = l - 1;
     90     for(int i = l; i <= r; ++i) {
     91         if(p[i].op == 1) {
     92             if(p[i].c > mid) modify(1, 1, n, p[i].a, p[i].b), p[i].v = 1;
     93             else p[i].v = 0;
     94         } else {
     95             int s = query(1, 1, n, p[i].a, p[i].b);
     96             if(p[i].c <= s) p[i].v = 1;
     97             else p[i].v = 0, p[i].c -= s;
     98         }
     99         t += !p[i].v;
    100     }
    101     sort(p + l, p + r + 1);
    102     work(a, mid, l, t);
    103     work(mid + 1, b, t + 1, r);
    104 }
    105 
    106 int main() {
    107     scanf("%d%d", &n, &m);
    108     for(int i = 1; i <= m; ++i) p[i].read(i);
    109     memset(ans + 1, 0x80, m * sizeof(int));
    110     work(-n, n, 1, m);
    111     for(int i = 1; i <= m; ++i)
    112         if(ans[i] >= -n) printf("%d
    ", ans[i]);
    113 }
    View Code
  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/oyking/p/3905850.html
Copyright © 2011-2022 走看看