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 }
View Code

 

posted @ 2020-08-17 01:34  canwinfor  阅读(120)  评论(0)    收藏  举报