• 线段树练习1


    题意

    n个数,m次操作,每次询问区间第k大,或者给区间加上一个数。

    $数据范围:1 ≤ n,m ≤ 10^5 ,1 ≤ k ≤ 10。$

    题解

    由于k很小,直接在线段树内维护,前k大的数。

    code

      1 #include<cstdio>
      2 #include<cstring>
      3 
      4 #define lson l,m,rt<<1
      5 #define rson m+1,r,rt<<1|1
      6 
      7 #define N 100010
      8 #define K 10
      9 
     10 int n,m;
     11 struct Tree {
     12     int data[K];
     13     Tree() {memset(data,0,sizeof(data));}
     14     Tree operator + (const Tree &a) const {
     15         Tree ret;
     16         int p1 = 0,p2 = 0;
     17         for (int i=0; i<K; ++i) 
     18             if (data[p1] > a.data[p2]) ret.data[i] = data[p1++];
     19             else ret.data[i] = a.data[p2++];
     20         return ret;
     21     }
     22 }t[N<<2];
     23 int a[N],tag[N<<2];
     24 
     25 inline int read() {
     26     int x = 0,f = 1;char ch = getchar();
     27     for (; ch<'0'||ch>'9'; ch = getchar())
     28         if (ch=='-') f = -1;
     29     for (; ch>='0'&&ch<='9'; ch = getchar())
     30         x = x*10+ch-'0';
     31     return x*f;
     32 }
     33 
     34 inline void pushup(int rt) {
     35     t[rt] = t[rt<<1] + t[rt<<1|1];
     36 }
     37 inline void pushdown(int rt) {
     38     if (tag[rt]) {
     39         tag[rt<<1] += tag[rt];
     40         for (int i=0; i<K; ++i) 
     41             if (t[rt<<1].data[i]) t[rt<<1].data[i] += tag[rt];//只加有的数字 
     42         tag[rt<<1|1] += tag[rt];
     43         for (int i=0; i<K; ++i) 
     44             if (t[rt<<1|1].data[i]) t[rt<<1|1].data[i] += tag[rt];
     45         tag[rt] = 0;
     46     }
     47 }
     48 void build(int l,int r,int rt) {
     49     if (l==r) {
     50         t[rt].data[0] = a[l];
     51         return ;
     52     } 
     53     int m = (l+r) >> 1;
     54     build (lson);
     55     build (rson);
     56     pushup(rt);
     57 }
     58 void update(int l,int r,int rt,int L,int R,int c) {
     59     if (L <= l && r <= R) {
     60         tag[rt] += c;
     61         for (int i=0; i<K; ++i) 
     62             if (t[rt].data[i]) t[rt].data[i] += c;
     63         return ;
     64     }
     65     pushdown(rt);
     66     int m = (l+r) >> 1;
     67     if (L <= m) update(lson,L,R,c);
     68     if (R > m)  update(rson,L,R,c);
     69     pushup(rt);
     70 }
     71 Tree query(int l,int r,int rt,int L,int R) {
     72     if (L <= l && r <= R) {
     73         return t[rt];
     74     }
     75     pushdown(rt);
     76     Tree ret;
     77     int m = (l+r) >> 1;
     78     if (L <= m) ret = ret + query(lson,L,R);
     79     if (R > m)  ret = ret + query(rson,L,R);
     80     return ret ;
     81 }
     82 int main() {
     83     
     84     int n = read(),m = read();
     85     for (int i=1; i<=n; ++i) a[i] = read();
     86     build(1,n,1);
     87     Tree ans;
     88     while (m--) {
     89         int opt = read(),l = read(),r = read(),k = read();
     90         if (opt==0) {
     91             if (r-l+1 < k) puts("-1");
     92             else {
     93                 ans = query(1,n,1,l,r);
     94                 printf("%d
    ",ans.data[k-1]);
     95             }
     96         }
     97         else update(1,n,1,l,r,k);
     98     }
     99     return 0;
    100 }

    by zhx p106 无题

  • 相关阅读:
    Bootstrap中的Dropdown悬停触发
    git常用命令整理
    ThinkPHP-项目模块分组后自定义类库文件放去哪?
    项目开发中常用的PHP实用代码算法
    1049. Counting Ones (30)
    1059. Prime Factors (25)
    1050. String Subtraction (20)
    观察者模式
    策略模式
    JVM剖析
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7791880.html
Copyright © 2020-2023  润新知