CF1439C 线段树

修改区间可以改对应l, r原数组的两个点,二者之间的点再慢慢下推修改

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cmath>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<string>
  7 #define ll long long
  8 using namespace std;
  9 
 10 const int N = 2e5 + 10;
 11 
 12 int n, q;
 13 ll tag, x, y;
 14 ll a[N];
 15 
 16 struct node
 17 {
 18     ll sum;
 19     int lazy;
 20 }t[N << 2];
 21 
 22 inline void push_up(int root)
 23 {
 24     t[root].sum = t[root << 1].sum + t[root << 1 | 1].sum;
 25 }
 26 
 27 inline void push_down(int root, int l, int r)//
 28 {
 29     t[root].sum = 1ll * (r - l + 1) * t[root].lazy;
 30     a[l] = a[r] = t[root].lazy;
 31     if(l < r){
 32         t[root << 1].lazy = t[root << 1 | 1].lazy = t[root].lazy;
 33     }
 34     t[root].lazy = 0;
 35 }
 36 
 37 inline void build(int l, int r, int root)
 38 {
 39     if(l == r){
 40         t[root].sum = a[l];
 41         t[root].lazy = 0;    
 42         return ;
 43     }
 44     int mid = (l + r) >> 1;
 45     build(l, mid, root << 1);
 46     build(mid + 1, r, root << 1 | 1);
 47     push_up(root);
 48 }
 49 
 50 inline void upd(int l, int r, int root, ll x, ll y)
 51 {
 52     if(t[root].lazy){
 53         push_down(root, l, r);
 54     }
 55     if(l > x || a[r] >= y)    return ;
 56     //当前区间左端点位于x右侧或右端点的值大于等于y,则无需更新 
 57     if(a[l] <= y && r <= x){
 58         t[root].lazy = y;
 59         push_down(root, l, r);//此处必须下推,确保a[l],a[r]已经修改,中间的a[]等下推再慢慢改 
 60         return ;
 61     }
 62     int mid = (l + r) >> 1;
 63     upd(l, mid, root << 1, x, y);
 64     upd(mid + 1, r, root << 1 | 1, x, y);
 65     push_up(root);
 66 }
 67 
 68 ll now;
 69 inline ll query(int l, int r, int root, ll x)
 70 {
 71     if(t[root].lazy){
 72         push_down(root, l, r);
 73     }
 74     if(r < x || a[r] > now)    return 0;//
 75     if(now >= t[root].sum && l >= x){
 76         now -= t[root].sum;
 77         return r - l + 1ll;
 78     }
 79     if(l == r)    return 0;////
 80     int mid = (l + r) >> 1;
 81     ll res = query(l, mid, root << 1, x);
 82     res += query(mid + 1, r, root << 1 | 1, x);
 83     return res;
 84 }
 85 
 86 int main(){
 87     scanf("%d%d",&n,&q);
 88     for(int i = 1 ; i <= n ; i++){
 89         scanf("%lld",&a[i]);
 90     }
 91     
 92     build(1, n, 1);
 93     for(int i = 1 ; i <= q ; i++){
 94         scanf("%lld%lld%lld",&tag,&x,&y);
 95         if(tag == 1){
 96             upd(1, n, 1, x, y);
 97         }else{
 98             now = y;
 99             printf("%lld
", query(1, n, 1, x));
100         }
101     }
102     
103     return 0;
104 }
原文地址:https://www.cnblogs.com/ecustlegendn324/p/14010334.html