• CF920F SUM and REPLACE


    题面

    题意:

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

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

    首先(d)是可以预处理出来的qwq。比如通过线性筛。

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

    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

    时间复杂度(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;
    
    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] ++;
    		}
    	}
    	scanf("%lld%lld", &n, &m);
    	for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
    	tree.build(1, n, 1);
    	for(int i = 1, x, y, z; i <= m; i ++){
    		scanf("%lld%lld%lld", &x, &y, &z);
    		if(x&1) tree.chenge(y, z, 1);
    		else{
    			int ans = 0;
    			tree.quary(y, z, 1, ans);
    			printf("%lld
    ", ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    关闭游标
    OCP-1Z0-053-200题-19题-601
    OCP-1Z0-053-200题-17题-99
    OCP-1Z0-053-200题-18题-100
    OCP-1Z0-053-V13.02-99题
    OCP-1Z0-053-200题-16题-98
    OCP-1Z0-053-200题-15题-15
    OCP-1Z0-053-200题-14题-675
    OCP-1Z0-053-200题-13题-97
    OCP-1Z0-053-200题-12题-96
  • 原文地址:https://www.cnblogs.com/Vanyun/p/13679377.html
Copyright © 2020-2023  润新知