cf920F SUM and REPLACE 树状数组+set 维护

题目:

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:

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

Print the answer for each SUM query.

分析:

我们考虑到每个数可以进行操作的数量不会很多,且D(1)=1,D(2)=2.

我们只需要暴力修改就行了,然后用树状数组求和.

如何优雅的暴力?

也就是说如何快速找出区间[l,r]内满足ai>2的i值.考虑用set维护还可以操作的下标的点,每次用lb,ub去找.暴力修改.

另外筛1-1e6中每个数的因子个数的方法需要注意.

 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
",sum(r)-sum(l-1));
61         }
62     }
63     return 0;
64 }
View Code
原文地址:https://www.cnblogs.com/sun-yinkai/p/8417093.html