Codeforces Round #250 (Div. 1) D. The Child and Sequence (线段树)

题目链接:http://codeforces.com/problemset/problem/438/D

给你n个数,m个操作,1操作是查询l到r之间的和,2操作是将l到r之间大于等于x的数xor于x,3操作是将下标为k的数变为x。

注意成段更新的时候,遇到一个区间的最大值还小于x的话就停止更新。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 using namespace std;
  5 typedef __int64 LL;
  6 const int MAXN = 1e5 + 5;
  7 struct segtree {
  8     int l , r;
  9     LL sum , Min;
 10 }T[MAXN << 2];
 11 LL res;
 12 
 13 void init(int p , int l , int r) {
 14     int mid = (l + r) >> 1;
 15     T[p].l = l , T[p].r = r;
 16     if(l == r) {
 17         scanf("%I64d" , &T[p].sum);
 18         T[p].Min = T[p].sum;
 19         return ;
 20     }
 21     init(p << 1 , l , mid);
 22     init((p << 1)|1 , mid + 1 , r);
 23     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
 24     T[p].Min = (T[p << 1].Min > T[(p << 1)|1].Min ? T[p << 1].Min : T[(p << 1)|1].Min);
 25 }
 26 
 27 void updata(int p , int l , int r , LL x) {
 28     int mid = (T[p].l + T[p].r) >> 1;
 29     if(T[p].Min < x) {
 30         return ;
 31     }
 32     if(T[p].l == T[p].r) {
 33         T[p].Min %= x;
 34         T[p].sum %= x;
 35         return ;
 36     }
 37     if(r <= mid) {
 38         updata(p << 1 , l , r , x);
 39     }
 40     else if(l > mid) {
 41         updata((p << 1)|1 , l , r , x);
 42     }
 43     else {
 44         updata(p << 1 , l , mid , x);
 45         updata((p << 1)|1 , mid + 1 , r , x);
 46     }
 47     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
 48     T[p].Min = (T[p << 1].Min > T[(p << 1)|1].Min ? T[p << 1].Min : T[(p << 1)|1].Min);
 49 }
 50     
 51 void updata2(int p , int index , LL x) {
 52     int mid = (T[p].l + T[p].r) >> 1;
 53     if(T[p].l == T[p].r && T[p].l == index) {
 54         T[p].sum = T[p].Min = x;
 55         return ;
 56     }
 57     if(index <= mid) {
 58         updata2(p << 1 , index , x);
 59     }
 60     else {
 61         updata2((p << 1)|1 , index , x);
 62     }
 63     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
 64     T[p].Min = (T[p << 1].Min > T[(p << 1)|1].Min ? T[p << 1].Min : T[(p << 1)|1].Min);
 65 }
 66 
 67 void query(int p , int l , int r) {
 68     int mid = (T[p].l + T[p].r) >> 1;
 69     if(l == T[p].l && T[p].r == r) {
 70         res += (LL)T[p].sum;
 71         return ;
 72     }
 73     if(r <= mid) {
 74         query(p << 1 , l , r);
 75     }
 76     else if(l > mid) {
 77         query((p << 1)|1 , l , r);
 78     }
 79     else {
 80         query(p << 1 , l , mid);
 81         query((p << 1)|1 , mid + 1 , r);
 82     }
 83 }
 84 
 85 int main()
 86 {
 87     int n , m , l , r , c;
 88     LL x;
 89     scanf("%d %d" , &n , &m);
 90     init(1 , 1 , n);
 91     while(m--) {
 92         scanf("%d" , &c);
 93         if(c == 1) {
 94             scanf("%d %d" , &l , &r);
 95             res = 0;
 96             query(1 , l , r);
 97             printf("%I64d
" , res);
 98         }
 99         else if(c == 2) {
100             scanf("%d %d %I64d" , &l , &r , &x);
101             updata(1 , l , r , x);
102             //cout << query(1 , 4 , 4) << endl;
103         }
104         else {
105             scanf("%d %I64d" , &l , &x);
106             updata2(1 , l , x);
107         }
108     }
109 }
原文地址:https://www.cnblogs.com/Recoder/p/5373777.html