Educational Codeforces Round 37 (Rated for Div. 2) F. SUM and REPLACE ###K //K
题目链接:https://codeforc.es/problemset/problem/920/F
题意: 有2种操作 第一种是 在l,r 区间内的数全部换成 这个数的因子个数 如 6 有1 2 3 6 所以6要换成4 第二种是查询 区间l r 内的和
思路:很套路的一种题目, 因为变因子数的操作不会很多, 一个数最多变6次就会到2 而1变化后还是1 所以只要全部暴力修改 也是 n次操作就能完成,
然后只需要维护区间内的最大值 在最大值小于等于2的时候 不用再修改了 即可 1e6的数 用nlogn 就可以求出每个数的因子数
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =1e6+10; 6 const int mod=1e9+7; 7 8 ll a[maxn]; 9 int f[maxn]; 10 11 struct ac 12 { 13 int l,r; 14 ll sum,max1; 15 void update() 16 { 17 max1=sum=f[sum]; 18 } 19 }; 20 ac tree[maxn*2]; 21 22 void pushup(int x) 23 { 24 tree[x].max1=max(tree[x<<1].max1,tree[x<<1|1].max1); 25 tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; 26 } 27 28 void build(int x,int l,int r) 29 { 30 tree[x].l=l; 31 tree[x].r=r; 32 if(l==r) 33 { 34 tree[x].max1=tree[x].sum=a[l]; 35 } 36 else 37 { 38 int mid=(l+r)/2; 39 build(x<<1,l,mid); 40 build(x<<1|1,mid+1,r); 41 pushup(x); 42 } 43 } 44 45 void update(int x,int l,int r) 46 { 47 int L=tree[x].l,R=tree[x].r; 48 if(tree[x].max1<=2) 49 return; 50 if(L==R) 51 { 52 tree[x].update(); 53 } 54 else 55 { 56 int mid=(L+R)/2; 57 if(l<=mid) update(x<<1,l,r); 58 if(r>mid) update(x<<1|1,l,r); 59 pushup(x); 60 } 61 } 62 63 ll query(int x,int l,int r) 64 { 65 int L=tree[x].l; 66 int R=tree[x].r; 67 if(l<=L&&R<=r) 68 { 69 return tree[x].sum; 70 } 71 else 72 { 73 ll ans=0; 74 int mid=(L+R)/2; 75 if(r>mid) ans+=query(x<<1|1,l,r); 76 if(l<=mid) ans+=query(x<<1,l,r); 77 return ans; 78 } 79 } 80 81 82 int main() 83 { 84 ios::sync_with_stdio(false); 85 cin.tie(0); 86 int n,m; 87 cin>>n>>m; 88 for(int i=1;i<maxn;i++) 89 { 90 for(int j=i;j<maxn;j+=i) 91 { 92 f[j]++; 93 } 94 } 95 for(int i=1;i<=n;i++) 96 { 97 cin>>a[i]; 98 } 99 build(1,1,n); 100 while(m--) 101 { 102 int t,l,r; 103 cin>>t>>l>>r; 104 if(t==1) 105 { 106 update(1,l,r); 107 } 108 else 109 { 110 cout<<query(1,l,r)<<'\n'; 111 } 112 } 113 114 115 116 117 }

浙公网安备 33010602011771号