1. 程式人生 > >Codefroces 920F SUM and REPLACE(線段樹)

Codefroces 920F SUM and REPLACE(線段樹)

ref define ise div blank == query force memset

SUM and REPLACE

題意:給你n個數,進行m次操作,分別是將區間[l,r]內的所有數替換成自己的因子數 和 對區間[l,r]進行求和。

題解:可以發現2的因子個數還是2,1的因子個數還是1,所以如果某個數被更新成1或者2之後就不需要再進行更新了。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 using namespace std;
 6 const int N = 3e5+5
; 7 const int M = 1e6+5; 8 ll tree[N<<2]; 9 bool ok[N<<2]; 10 int num[M], a[N]; 11 int n, m; 12 void PushUp(int rt) 13 { 14 tree[rt] = tree[rt<<1] + tree[rt<<1|1]; 15 ok[rt] = ok[rt<<1] && ok[rt<<1|1]; 16 } 17 void Build(int l, int r, int rt) 18 {
19 if(l == r) 20 { 21 tree[rt] = a[l]; 22 if(tree[rt] == 1 || tree[rt] == 2) ok[rt] = 1; 23 else ok[rt] = 0; 24 return ; 25 } 26 int m = l+r >> 1; 27 Build(lson); 28 Build(rson); 29 PushUp(rt); 30 } 31 ll Query(int L, int R, int l, int r, int
rt) 32 { 33 if(L <= l && r <= R) 34 return tree[rt]; 35 int m = l+r >> 1; 36 ll ans = 0; 37 if(L <= m) ans += Query(L,R,lson); 38 if(m < R) ans += Query(L,R,rson); 39 return ans; 40 } 41 42 void Revise(int L, int R, int l, int r, int rt) 43 { 44 if(ok[rt]) return ; 45 if(l == r) 46 { 47 tree[rt] = num[tree[rt]]; 48 if(tree[rt] == 1 || tree[rt] == 2) ok[rt] = 1; 49 return ; 50 } 51 int m = l+r >> 1; 52 if(L <= m) Revise(L,R,lson); 53 if(m < R) Revise(L,R,rson); 54 PushUp(rt); 55 } 56 int main() 57 { 58 ios::sync_with_stdio(false); 59 cin.tie(0); 60 cout.tie(0); 61 memset(num, 0, sizeof(num)); 62 for(int i = 1; i < M; i++) 63 for(int j = i; j < M; j+=i) 64 num[j]++; 65 cin >> n >> m; 66 for(int i = 1; i <= n; i++) 67 cin >> a[i]; 68 Build(1,n,1); 69 int q, l, r; 70 while(m--) 71 { 72 cin >> q >> l >> r; 73 if(q == 2) 74 cout << Query(l,r,1,n,1) << endl; 75 else 76 Revise(l,r,1,n,1); 77 } 78 return 0; 79 }

Codefroces 920F SUM and REPLACE(線段樹)