• LibreOJ #6284


    题目链接:#6284. 数列分块入门 8

    题目大意

    给出一个长为 (n) 的数列,以及 (n) 个操作,操作涉及区间询问等于一个数 (c) 的元素,并将这个区间的所有元素改为 (c)

    solution

    又是我们喜爱的分块

    我们怎么做呢, 我们讲区间内全部相同的打一个标记, 记录这个区间的值,然后计算的时候加上这个区间的长度就好了,然后不相同的我们直接暴力查找就好了

    我们在散块处理的时候记得把标记下放,不然会哭的

    Code:

    /**
    *    Author: Alieme
    *    Data: 2020.9.8
    *    Problem: LibreOJ #6284
    *    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 200010
    
    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], id[MAXN], f[MAXN];
    
    inline void reset(int x) {
    	if (f[x] == -1) return ;
    	for (rr int i = (x - 1) * len + 1; i <= min(x * len, n); i++) a[i] = f[x];
    	f[x] = -1;
    }
    
    inline void change(int l, int r, int x) {
    	int start = id[l], end = id[r];
    	if (start == end) {
    		reset(start);
    		for (rr int i = l; i <= r; i++) a[i] = x;
    		return ;
    	}
    	reset(start), reset(end);
    	for (rr int i = l; id[i] == start; i++) a[i] = x;
    	for (rr int i = start + 1; i < end; i++) f[i] = x;
    	for (rr int i = r; id[i] == end; i--) a[i] = x;
    }
    
    inline int query(int l, int r, int x) {
    	int start = id[l], end = id[r], ans = 0;
    	if (start == end) {
    		reset(start);
    		for (rr int i = l; i <= r; i++) if (a[i] == x) ans++;
    		return ans;
    	}
    	reset(start), reset(end);
    	for (rr int i = l; id[i] == start; i++) if (a[i] == x) ans++;
    	for (rr int i = start + 1; i < end; i++) 
    		if (f[i] == x) ans += len;
    		else if (f[i] == -1) for (rr int j = (i - 1) * len + 1; j <= i * len; j++) if (a[j] == x) ans++;
    	for (rr int i = r; id[i] == end; i--) if (a[i] == x) ans++;
    	return ans;
    }
    
    signed main() {
    	// freopen("a1.in", "r", stdin);
    	// freopen("a.out", "w", stdout);
    	n = read();
    	len = sqrt(n);
    	for (rr int i = 1; i <= n; i++) a[i] = read(), id[i] = (i - 1) / len + 1, f[id[i]] = -1;
    	for (rr int i = 1; i <= n; i++) {
    		int l = read(), r = read(), c = read();
    		cout << query(l, r, c) << "
    ";
    		change(l, r, c);
    	}
    }
    
  • 相关阅读:
    zoj 1649 Rescue
    poj 1659 Frogs' Neighborhood
    hdu 1385 Minimum Transport Cost
    hdu 2680 Choose the best route
    写了一下午的dijkstra。突然发现我写的根本不是dijkstra。。。。是没优化过的BFS.......
    hdu 1548 A strange lift
    hdu 2066 一个人的旅行
    hdu 2544 最短路
    洛谷 P3253 [JLOI2013]删除物品 解题报告
    洛谷 P10P1343 地震逃生 改错
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13641836.html
Copyright © 2020-2023  润新知