数列分块入门 8
这题我们只需设个targe[i]表示第i块是否都为一个数,如果是,则targe[i]等于这个数,否则等于-1
然后暴力搞就可以了。以下大佬分析
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #include <stdio.h> #include <algorithm> #include <map> #include <queue> #include <set> #include <sstream> #include <vector> #include <cmath> #include <stack> #include <random> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define LD long double #define LL long long #define PI acos(-1.0) #define INF 0x3f3f3f3f #define inf 1<<30 #define ull unsigned long long const int Mod = 10007; const int maxn = 1e6 + 5; int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int n, m, block; int opt, l, r, c; int a[maxn]; int bel[maxn]; int targe[maxn]; void rest(int x) { if (targe[bel[x]] == -1)return; for (int i = (bel[x] - 1) * block + 1; i <= min(n, bel[x] * block); i++) { a[i] = targe[bel[x]]; } targe[bel[x]] = -1; } void search(int L, int R, int val) { int ans = 0; rest(L); for (int i = L; i <= min(bel[L] * block, R); i++) { if (a[i] == val) ans++; else a[i] = val; } if (bel[L] != bel[R]) { rest(R); for (int i = (bel[R] - 1) * block + 1; i <= R; i++) { if (a[i] == val) ans++; else a[i] = val; } for (int i = bel[L] + 1; i <= bel[R] - 1; i++) { if (targe[i] == -1) { for (int j = (i - 1) * block + 1; j <= i * block; j++) { if (a[j] == val) ans++; else a[j] = val; } targe[i] = val; } else { if (targe[i] == val) ans += block; else targe[i] = val; } } } printf("%d\n", ans); } int main() { n = read(); block = sqrt(n); m = n / block; if (n % block)m++; memset(targe, -1, sizeof(targe)); for(int i= 1; i <= n; i++) { a[i] = read(); bel[i] = (i - 1) / block + 1; } for (int i = 1; i <= n; i++) { l = read(); r = read(); c = read(); search(l, r, c); } }