• 洛谷 P2801


    题目链接: P2801 教主的魔法

    题目大意

    一个序列 (n) 有区间加和及查询区间有多少个元素大于 (c)

    solution

    我们对每个块进行操作,对于每个块排序

    修改操作:对于整块我们记录一下加的之即可,顺序没有改变,然后对于不足整块,我们直接加和然后排序

    查询操作:对于整块我们 lower_bound 查找即可, 用块长减去查找的位置即可, 然后对于不足整块, 我们直接枚举查找

    Code

    /**
    *    Author: Alieme
    *    Data: 2020.9.8
    *    Problem: Lougu P2801
    *    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 1000010
    
    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, m;
    
    int a[MAXN], b[MAXN], id[MAXN], v[MAXN];
    
    inline void update(int x) {
    	int l = (x - 1) * len + 1, r = min(x * len, n);
    	for (rr int i = l; i <= r; i++) b[i] = a[i];
    	sort(b + l, b + r + 1);
    }
    
    inline void add(int l, int r, int x) {
    	int start = id[l], end = id[r];
    	if (start == end) {
    		for (rr int i = l; i <= r; i++) a[i] += x;
    		update(id[l]);
    		return ;
    	}
    	for (rr int i = l; id[i] == start; i++) a[i] += x; update(start);
    	for (rr int i = start + 1; i < end; i++) v[i] += x;
    	for (rr int i = r; id[i] == end; i--) a[i] += x; update(end);
    }
    
    inline int fin(int pid, int x) {
    	int l = (pid - 1) * len + 1, r = min(pid * len, n);
    	return lower_bound(b + l, b + r + 1, x - v[pid]) - (b + l);
    }
    
    inline int query(int l, int r, int x) {
    	int ans = 0, start = id[l], end = id[r];
    	if (start == end) {
    		for (rr int i = l; i <= r; i++) if (a[i] + v[start] >= x) ans++;
    		return ans;
    	}
    	for (rr int i = l; id[i] == start; i++) if (a[i] + v[id[i]] >= x) ans++;
    	for (rr int i = start + 1; i < end; i++) ans += len - fin(i, x);
    	for (rr int i = r; id[i] == end; i--) if (a[i] + v[id[i]] >= x) ans++;
    	return ans;
    }
    
    signed main() {
    	n = read();
    	m = read();
    	len = sqrt(n);
    	for (rr int i = 1; i <= n; i++) a[i] = read(), id[i] = (i - 1) / len + 1;
    	for (rr int i = len; i <= n; i += len) update(id[i]);
    	for (rr int i = 1; i <= m; i++) {
    		char opt;
    		cin >> opt;
    		int l = read(), r = read(), c = read();
    		if (opt == 'M') add(l, r, c);
    		if (opt == 'A') cout << query(l, r, c) << "
    ";
    	}
    }
    
    
  • 相关阅读:
    复杂网络常用数据集网站
    01单人决策问题
    《无线网络安全技术》阅读笔记
    最优化理论基础
    测试layer控件,除了ie报错其它浏览器都生效
    Native App、Web App、Hybrid App
    有些效果在IE下运行时,IE下开调试模式才显示正常是什么原因?
    关于Content-Type中application/x-www-form-urlencoded 和 multipart/form-data的区别及用法
    js表单提交的三种方式
    前端涉及的所有知识体系
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13643365.html
Copyright © 2020-2023  润新知