cf920F SUM and REPLACE 樹狀數組+set 維護

題目:c++

Let D(x) be the number of positive divisors of a positive integer x. For example, D(2) = 2 (2 is divisible by 1 and 2), D(6) = 4 (6 is divisible by 1, 2, 3 and 6).數組

You are given an array a of n integers. You have to process two types of queries:ide

  1. REPLACE l r — for every  replace ai with D(ai);
  2. SUM l r — calculate .

Print the answer for each SUM query.spa

分析:code

咱們考慮到每一個數能夠進行操做的數量不會不少,且D(1)=1,D(2)=2.orm

咱們只須要暴力修改就好了,而後用樹狀數組求和.blog

如何優雅的暴力?get

也就是說如何快速找出區間[l,r]內知足ai>2的i值.考慮用set維護還能夠操做的下標的點,每次用lb,ub去找.暴力修改.it

另外篩1-1e6中每一個數的因子個數的方法須要注意.event

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAXN=3e5+7;
 5 int N,M;
 6 LL a[MAXN],val[MAXN];
 7 int D[1000001];
 8 inline int lowbit(int i){
 9     return i&-i;
10 }
11 LL sum(int x){
12     LL res=0;
13     while(x){
14         res+=a[x];
15         x-=lowbit(x);
16     }
17     return res;
18 }
19 void add(int i,int x){
20     while(i<=N){
21         a[i]+=x;
22         i+=lowbit(i);
23     }
24 }
25 int getD(long long x){
26     return D[x];
27 }
28 int main(){
29     for(int i=1;i<=1000000;++i){
30         for(int j=i;j<=1000000;j+=i){
31             D[j]++;
32         }
33     }
34     scanf("%d%d",&N,&M);
35     set<int>st;
36     for(int i=1;i<=N;++i){
37         scanf("%I64d",&val[i]);
38         if(val[i]>2)st.insert(i);
39         add(i,val[i]);
40     }
41     while(M--){
42         int t,l,r;scanf("%d%d%d",&t,&l,&r);
43         if(t==1){
44             auto first=st.lower_bound(l);
45             auto last=st.upper_bound(r);
46             queue<int>q;
47             while(first!=last){
48                 int i=*first;
49                 int x=getD(val[i]);
50                 add(i,x-val[i]);
51                 val[i]=x;
52                 if(x<=2)q.push(i);
53                 first++;
54             }
55             while(!q.empty()){
56                 int now=q.front();q.pop();
57                 st.erase(now);
58             }
59         }else{
60             printf("%I64d\n",sum(r)-sum(l-1));
61         }
62     }
63     return 0;
64 }
View Code
相關文章
相關標籤/搜索