ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF920F SUM and REPLACE

2020-09-16 15:31:21  阅读:11  来源: 互联网

标签:ch temp read SUM long REPLACE int CF920F getchar


题面

题意:

给定\(n\)个数的数组\(a\),\(m\)次操作。操作有两种:

  1. 将 \(i\in[l,r]\) 中的所有 \(a_i\) 替换为 \(d(a_i)\)。\(d(x)\) 表示 \(x\) 的正约数的个数。
  2. 求 \(\displaystyle\sum_{i=l}^r a_i\)。

\(d\)是可以预处理出来的。

线性筛太麻烦了?有这样一种预处理方式:

for(int i = 1; i <= 1000000; i ++){
	for(int j = i; j <= 1000000; j += i){
		d[j] ++;
	}
}

实践证明它是不会T的。

我们通过观察显然可以发现,在进行好多次操作之后,每个数会一直是\(1\)或\(2\)。

所以对于一个数我们直接暴力修改。毕竟最多的修改次数不会超过\(6\)次。

在维护区间和的同时维护一个区间最大值。

当修改过程中某个区间最大值小于等于\(2\)的时候,说明我们这次的操作是无能的无效的,直接返回即可。

注意要开long long,不然会爆掉orz。所以直接define int long long qwq

时间复杂度\(O(mlogn)\)。

代码:

#include <bits/stdc++.h>
#define ls (now << 1)
#define rs (now<<1|1)
#define mid ((l+r)>>1)
#define int long long
using namespace std;

namespace fast_read{
	template<typename temp>
	temp read(temp &x){
		x = 0;temp f = 1;char ch;
		while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
		for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
		return x *= f;
	}
	template <typename temp, typename ...Args>
	void read(temp& a, Args& ...args){read(a), read(args...);}
	inline int read(){
		int x = 0, f = 1;char ch;
		while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
		for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
		return x *= f;
	}
}using namespace fast_read;

const int maxn = 3e5+10;

int n, m, a[maxn], d[1000010];

struct seg_tree{
	struct nodes{
		int l, r, sum, max_num;
	}node[maxn<<2];
	void up(int now){return (void)(node[now].sum = node[ls].sum + node[rs].sum, node[now].max_num = max(node[ls].max_num, node[rs].max_num));}
	void build(int l, int r, int now){
		node[now].l = l, node[now].r = r;
		if(l == r) return (void)(node[now].sum = a[l], node[now].max_num = a[l]);
		build(l, mid, ls), build(mid+1, r, rs);
		return up(now);
	}
	void chenge(int l, int r, int now){
		if(r < node[now].l or node[now].r < l or node[now].max_num <= 2) return;
		if(node[now].l == node[now].r) return(void) (node[now].max_num = node[now].sum = d[node[now].sum]);
		chenge(l, r, ls), chenge(l, r, rs);
		return up(now);
	}
	void quary(int l, int r, int now, int &ans){
		if(r < node[now].l or node[now].r < l) return;
		if(l <= node[now].l and node[now].r <= r) return (void)(ans += node[now].sum);
		quary(l, r, ls, ans), quary(l, r, rs, ans);
		return up(now);
	}
}tree;

signed main(){
	for(int i = 1; i <= 1000000; i ++){
		for(int j = i; j <= 1000000; j += i){
			d[j] ++;
		}
	}
	read(n, m);
	for(int i = 1; i <= n; i ++) read(a[i]);
	tree.build(1, n, 1);
	for(int i = 1, x, y, z; i <= m; i ++){
		read(x, y, z);
		if(x&1) tree.chenge(y, z, 1);
		else{
			int ans = 0;
			tree.quary(y, z, 1, ans);
			printf("%lld\n", ans);
		}
	}
	return 0;
}

标签:ch,temp,read,SUM,long,REPLACE,int,CF920F,getchar
来源: https://www.cnblogs.com/Vanyun/p/13679377.html

专注分享技术,共同学习,共同进步。侵权联系[admin#icode9.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有