CF438 The Child and Sequence

題意:c++

給定一個長度爲n的非負整數序列a,你須要支持如下操做:
1)給定l,r,輸出a[l] + a[l+1] + ... + a[r]git

2)給定l,r,x, 將a[l]、a[l+1]、....、a[r]x取模ui

3)給定k,y,將a[k]修改成yspa

n, m <= 100000,a[i], x, y <= 109code


對於操做(1)(3)很是簡單,線段樹基本操做blog

問題是操做(2),顯然的是咱們不能對區間和取模,這樣就很難受get

可是咱們能夠想到,一個數如果比模數小,就不須要取模,而一個數w有效取模次數最多爲log(w)it

同時單個數被有效取模的一次只會花費O(logn)class

所以每次修改至多使複雜度增長O(lognlogw)date

這樣咱們對於區間l, r暴力對每一個能取模的數取模便可

最後時間複雜度爲O(mlognlogw)

 

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define uint unsigned int
 4 #define ull unsigned long long
 5 using namespace std;  6 const int maxn = 100010;  7 struct shiki {  8  ll maxx, sum;  9 }tree[maxn << 2]; 10 int n, m; 11 ll a[maxn]; 12 
13 inline ll read() { 14     ll x = 0, y = 1; 15     char ch = getchar(); 16     while(!isdigit(ch)) { 17         if(ch == '-') y = -1; 18         ch = getchar(); 19  } 20     while(isdigit(ch)) { 21         x = (x << 1) + (x << 3) + ch - '0'; 22         ch = getchar(); 23  } 24     return x * y; 25 } 26 
27 inline void maintain(int pos) { 28     int ls = pos << 1, rs = pos << 1 | 1; 29     tree[pos].maxx = max(tree[ls].maxx, tree[rs].maxx); 30     tree[pos].sum = tree[ls].sum + tree[rs].sum; 31 } 32 
33 void build(int pos, int l, int r) { 34     if(l == r) { 35         tree[pos].maxx = tree[pos].sum = a[l]; 36         return; 37  } 38     int mid = l + r >> 1; 39     build(pos << 1, l, mid); 40     build(pos << 1 | 1, mid + 1, r); 41  maintain(pos); 42 } 43 
44 void get_mod(int pos, int L, int R, int l, int r, ll mod) { 45     if(l > R || r < L) return; 46     if(tree[pos].maxx < mod) return; 47     if(l == r) { 48         tree[pos].sum %= mod; 49         tree[pos].maxx %= mod; 50         return; 51  } 52     int mid = l + r >> 1; 53     get_mod(pos << 1, L, R, l, mid, mod); 54     get_mod(pos << 1 | 1, L, R, mid + 1, r, mod); 55  maintain(pos); 56 } 57 
58 void update(int pos, int aim, int l, int r, ll val) { 59     if(l == r && l == aim) { 60         tree[pos].maxx = tree[pos].sum = val; 61         return; 62  } 63     int mid = l + r >> 1; 64     if(aim <= mid) update(pos << 1, aim, l, mid, val); 65     else update(pos << 1 | 1, aim, mid + 1, r, val); 66  maintain(pos); 67 } 68 
69 ll query_sum(int pos, int L, int R, int l, int r) { 70     if(l > R || r < L) return 0; 71     if(l >= L & r <= R) return tree[pos].sum; 72     int mid = l + r >> 1; 73     return query_sum(pos << 1, L, R, l, mid) + query_sum(pos << 1 | 1, L, R, mid + 1, r); 74 } 75 
76 int main() { 77     n = read(), m = read(); 78     for(int i = 1; i <= n; ++i) a[i] = read(); 79     build(1, 1, n); 80     for(int i = 1; i <= m; ++i) { 81         int opt = read(), x = read(), y = read(); 82         if(opt == 1) printf("%I64d\n", query_sum(1, x, y, 1, n)); 83         if(opt == 2) { 84             ll p = read(); 85             get_mod(1, x, y, 1, n, p); 86  } 87         if(opt == 3) update(1, x, 1, n, y); 88  } 89     return 0; 90 }
相關文章
相關標籤/搜索