您的位置:首页 > 其它

Codeforces 920F - SUM and REPLACE【线段树】

2018-02-05 13:35 387 查看
F. SUM and REPLACE
time limit per test 2seconds
memory limit per test     256megabytes

Let
D(x)
be the numberof positive divisors of a positive integer x.
For example, D(2) = 2
(2
is divisible by1
and2),D(6) = 4
(6
is divisible by1,2,3
and6).

You are given an arraya
ofn
integers. Youhave to process two types of queries:

1.    REPLACElr
— for every

  replace
ai
with D(ai);

2.    SUMlr
— calculate 


Print the answer for eachSUM
query.
Input

The first line contains two integersn
andm
(1 ≤ n, m ≤ 3·105)
— the numberof elements in the array and the number of queries to process, respectively.

The second line containsn
integersa1,a2,
..., an
(1 ≤ ai ≤ 106)
— the elementsof the array.

Thenm
lines follow,each containing 3
integers ti,li,ri
denoting i-th
query. If ti = 1,
then i-th
query is REPLACEliri,
otherwise it'sSUMliri
(1 ≤ ti ≤ 2,1 ≤ li ≤ ri ≤ n).

There is at least oneSUM
query.
Output
For eachSUM
query print the answer to it.
Example
Input

7 6

6 4 1 10 3 2 4

2 1 7

2 4 5

1 3 5

2 4 4

1 5 7

2 1 7
Output

30

13

4

22
 

【题意】

给定n个数,现在有两种操作,第一种操作是将【L,R】范围内的所有数都替换为其因子个数,第二种操作是查询【L,R】范围内所有数的和。

【思路】

首先考虑如何快速得到一系列数的因子个数,我们只要用筛法预处理即可。

然后考虑到一个数的因子个数最大不超过30,而1的因子个数为1,2的因子个数为2,也就是说更新到1,2后不用再更新,那么每个点最多更新6次,于是我们只要暴力更新即可。

对于操作二,其实就是线段树的基本操作——区间求和。

#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

typedef long long ll;
const int maxn = 1000005;
const ll mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;

int n,m;
int d[maxn];
int a[maxn];
ll tree[maxn<<2];
int Max[maxn<<2];

void init()
{
mst(d,0);
for(int i=1;i<maxn;i++)
for(int j=i;j<maxn;j+=i)
{
d[j]++;
}
}

void pushup(int rt)
{
tree[rt]=tree[rt<<1|1]+tree[rt<<1];
Max[rt]=max(Max[rt<<1|1],Max[rt<<1]);
}

void build(int l,int r,int rt)
{
if(l==r)
{
tree[rt]=Max[rt]=a[l];
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}

void update(int x,int y,int l,int r,int rt)
{
if(Max[rt]<=2) return;
if(l==r)
{
tree[rt]=Max[rt]=d[tree[rt]];
return;
}
int mid=(l+r)>>1;
if(x<=mid) update(x,y,lson);
if(y>mid) update(x,y,rson);
pushup(rt);
}

ll query(int x,int y,int l,int r,int rt)
{
if(x<=l&&r<=y) return tree[rt];
int mid=(l+r)>>1;
ll ans=0;
if(x<=mid) ans+=query(x,y,lson);
if(y>mid) ans+=query(x,y,rson);
return ans;
}

int main()
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,n,1);
int op,l,r;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&l,&r);
if(op==1) update(l,r,1,n,1);
else printf("%lld\n",query(l,r,1,n,1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  920F - SUM and REPLA