[LOJ6278]数列分块入门 2
题目描述
输入格式
输出格式
样例
数据范围与提示
这道水题调了我接近50分钟,不开心。
一开始以为没开longlong,实际上没有仔细读题,我还以为是求区间中小于等于$c^2$的个数呢...然后就因为没仔细读题贡献了接近一页的wa。
这题分块做,对于每个块,在块内进行排序,为了方便用vector存储就行了,然后修改的时候,整块直接打标记,零散的块整个暴力重构,查询整块在vector内二分,零散的暴力。
反正题的数据范围也不强,这个水题随便写写就能过。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <queue> using namespace std; #define reg register #define int long long inline int read() { int res = 0;char ch=getchar();bool fu=0; while(!isdigit(ch))fu|=(ch=='-'),ch=getchar(); while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar(); return fu?-res:res; } int Bl = 500; #define N 50005 int n; int a[N]; int belong[N]; int L[5005], R[5005], tag[5005]; vector <int> ve[5005]; signed main() { n = read(); for (reg int i = 1 ; i <= n ; i ++) a[i] = read(); Bl = sqrt(n); for (reg int i = 1 ; i <= n ; i ++) { belong[i] = (i - 1) / Bl + 1; if (!L[belong[i]]) L[belong[i]] = i, R[belong[i]-1] = i - 1; } R[belong[n]] = n; for (reg int i = 1 ; i <= n ; i ++) ve[belong[i]].push_back(a[i]); for (reg int i = 1 ; i <= belong[n] ; i ++) sort(ve[i].begin(), ve[i].end()); int Q = n; while(Q--) { int opt = read(), l = read(), r = read(), c = read(); if (opt == 0) { if (belong[l] == belong[r]) { ve[belong[l]].clear(); for (reg int i = l ; i <= r ; i ++) a[i] += c; for (reg int i = L[belong[l]] ; i <= R[belong[l]] ; i ++) ve[belong[i]].push_back(a[i]); sort(ve[belong[l]].begin(), ve[belong[l]].end()); } else if (belong[l] + 1 == belong[r]) { ve[belong[l]].clear(); for (reg int i = l ; i <= R[belong[l]] ; i ++) a[i] += c; for (reg int i = L[belong[l]] ; i <= R[belong[l]] ; i ++) ve[belong[i]].push_back(a[i]); sort(ve[belong[l]].begin(), ve[belong[l]].end()); ve[belong[r]].clear(); for (reg int i = L[belong[r]] ; i <= r ; i ++) a[i] += c; for (reg int i = L[belong[r]] ; i <= R[belong[r]] ; i ++) ve[belong[i]].push_back(a[i]); sort(ve[belong[r]].begin(), ve[belong[r]].end()); } else { for (reg int i = belong[l] + 1 ; i <= belong[r] - 1 ; i ++) tag[i] += c; ve[belong[l]].clear(); for (reg int i = l ; i <= R[belong[l]] ; i ++) a[i] += c; for (reg int i = L[belong[l]] ; i <= R[belong[l]] ; i ++) ve[belong[i]].push_back(a[i]); sort(ve[belong[l]].begin(), ve[belong[l]].end()); ve[belong[r]].clear(); for (reg int i = L[belong[r]] ; i <= r ; i ++) a[i] += c; for (reg int i = L[belong[r]] ; i <= R[belong[r]] ; i ++) ve[belong[i]].push_back(a[i]); sort(ve[belong[r]].begin(), ve[belong[r]].end()); } } else { c *= c; int ans = 0; if (belong[l] == belong[r]) { for (reg int i = l ; i <= r ; i ++) if (a[i] + tag[belong[i]] < c) ans++; printf("%lld\n", ans); } else if (belong[l] + 1 == belong[r]) { for (reg int i = l ; i <= r ; i ++) if (a[i] + tag[belong[i]] < c) ans++; printf("%lld\n", ans); } else { for (reg int i = l ; i <= R[belong[l]] ; i ++) if (a[i] + tag[belong[i]] < c) ans++; for (reg int i = L[belong[r]] ; i <= r ; i ++) if (a[i] + tag[belong[i]] < c) ans++; for (reg int i = belong[l] + 1 ; i <= belong[r] - 1 ; i ++) ans += lower_bound(ve[i].begin(), ve[i].end(), c - tag[i]) - ve[i].begin(); printf("%lld\n", ans); } } } return 0; }