zoukankan      html  css  js  c++  java
  • LibreOJ #6281

    题目链接:#6281. 数列分块入门 5

    题目大意

    给出一个长为 (n) 的数列 (a_1, a_2, ..., a_m) ,以及 (n) 个操作,操作涉及区间开方,区间求和。

    solution

    对于这道题我们发现, 一个数最多被开方 (5) 次, (5) 次之后所有的数就都变成了 (1)(0)

    所以我们的操作是这样的:

    修改操作: 我们对整块打个标记,如果该块全部无法在开根了,我们在整块操作时就不用管了,然后直接暴力开根整块即可,对于散块,我们也是直接暴力开根加和即可

    查询操作: 我们对于散块直接加,对于整块我们加上总和即可

    Code:

    /**
    *    Author: Alieme
    *    Data: 2020.9.8
    *    Problem: LibreOJ #6281
    *    Time: O()
    */
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    #define int long long
    #define rr register
    
    #define inf 1e9
    #define MAXN 100010
    
    using namespace std;
    
    inline int read() {
    	int s = 0, f = 0;
    	char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    	return f ? -s : s;
    }
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    int n, len;
    
    int a[MAXN], v[MAXN], id[MAXN], sum[MAXN];
    
    bool vis[MAXN];
    
    inline void update(int x) {
    	if (vis[x]) return ;
    	vis[x] = 1;
    	sum[x] = 0;
    	for (rr int i = (x - 1) * len + 1; i <= x * len; i++) {
    		a[i] = sqrt(a[i]), sum[x] += a[i];
    		if (a[i] > 1) vis[x] = 0;
    	}
    }
    
    inline void add(int l, int r) {
    	int start = id[l], end = id[r];
    	if (start == end) {
    		for (rr int i = l; i <= r; i++) sum[start] -= a[i], a[i] = sqrt(a[i]), sum[start] += a[i];
    		return ;
    	}
    	for (rr int i = l; id[i] == start; i++) sum[start] -= a[i], a[i] = sqrt(a[i]), sum[start] += a[i];
    	for (rr int i = start + 1; i < end; i++) update(i);
    	for (rr int i = r; id[i] == end; i--) sum[end] -= a[i], a[i] = sqrt(a[i]), sum[end] += a[i];
    }
    
    inline int query(int l, int r) {
    	int start = id[l], end = id[r], ans = 0;
    	if (start == end) {
    		for (rr int i = l; i <= r; i++) ans += a[i];
    		return ans;
    	}
    	for (rr int i = l; id[i] == start; i++) ans += a[i];
    	for (rr int i = start + 1; i < end; i++) ans += sum[i];
    	for (rr int i = r; id[i] == end; i--) ans += a[i]; 
    	return ans;
    }
    
    signed main() {
    	n = read();
    	len = sqrt(n);
    	for (rr int i = 1; i <= n; i++) a[i] = read(), id[i] = (i - 1) / len + 1, sum[id[i]] += a[i];
    	while (n--) {
    		int opt = read(), l = read(), r = read(), c = read();
    		if (opt == 0) add(l, r);
    		if (opt == 1) cout << query(l, r) << "
    ";
    	}
    }
    
  • 相关阅读:
    提取ecshop的mysql类
    phpexcel读取excel的xls xlsx csv格式
    Awstats显示国家地区插件GeoIP安装
    GeoIP Legacy City数据库安装说明
    JavaArrayList和数组间的相互转换
    mysql 初步认识
    HTTP ContentType
    ibatis 增加调试方法
    你了解Java中的Future吗?
    Java 环境问题总结
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13641826.html
Copyright © 2011-2022 走看看