帮我卡常,祝你们成功。
好吧我自己也不知道我为什么卡不过去,感觉算法是对的。
是我人傻常数大吗。。。
#include <cstdio>
template <typename T>
inline T mn(T x, T y) {return x < y ? x : y;}
template <typename T>
inline T mx(T x, T y) {return x > y ? x : y;}
template <typename T>
inline void chmin(T &x, T y) {(x > y) && (x = y);}
template <typename T>
inline void chmax(T &x, T y) {(x < y) && (x = y);}
template <typename T>
inline void read(T &x){
x = 0;int fu = 1;
char c = getchar();
while(c > 57 || c < 48){
if(c == 45) fu = -1;
c = getchar();
}
while(c <= 57 && c >= 48){
x = (x << 3) + (x << 1) + c - 48;
c = getchar();
}
x *= fu;
}
template <typename T>
inline void fprint(T x){
if(x < 0) putchar(45), x = -x;
if(x > 9) fprint(x / 10);
putchar(x % 10 + 48);
}
template <typename T>
inline void fprint(T x, char ch){
fprint(x);putchar(ch);
}
#define MAXN 1000005
#define MAXM 500005
#define V 100007
#define block 888
const int B = MAXN / block + 5;
int n, m, a[MAXN];
int ans[MAXM], bel[MAXN];
int fa[MAXN], sz[MAXN], rt[V], val[MAXN];
int fst[B], lst[B];
int opt[MAXM], l[MAXM], r[MAXM], x[MAXM];
int tag, R;
int find(int x){
if(fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
inline void merge(int x, int y){
if(rt[y]) fa[rt[x]] = rt[y];
else rt[y] = rt[x], val[rt[y]] = y;
sz[y] += sz[x];
sz[x] = rt[x] = 0;
}
inline void rebuild(int x){
for (register int i = fst[x];i <= lst[x];i ++) a[i] = val[find(i)], sz[a[i]] = rt[a[i]] = 0, a[i] -= tag;
for (register int i = fst[x];i <= lst[x];i ++) fa[i] = 0;
}
int tot = -0x3f3f3f3f;
inline void build(int x){
tag = 0;R = -0x3f3f3f3f;
for (register int i = fst[x];i <= lst[x];i ++) {
chmax(R, a[i]);
if(!rt[a[i]]) rt[a[i]] = i, val[i] = a[i];
fa[i] = rt[a[i]];
sz[a[i]] ++;
}
}
int main(){
read(n);read(m);
tot = -0x3f3f3f3f;
for (register int i = 1;i <= n;i ++){
read(a[i]);bel[i] = (i - 1) / block + 1;
if(!fst[bel[i]]) fst[bel[i]] = i;
lst[bel[i]] = i;
chmax(tot, a[i]);
}
for (register int i = 1;i <= m;i ++) read(opt[i]), read(l[i]), read(r[i]), read(x[i]);
for (register int i = 1;i <= bel[n];i ++){
build(i);
for (register int j = 1;j <= m;j ++){
if(opt[j] == 1){
if(bel[l[j]] == bel[r[j]]){
if(bel[l[j]] ^ i) continue;
rebuild(i);
for (register int k = l[j];k <= r[j];k ++)
if(a[k] > x[j]) a[k] -= x[j];
build(i);
}
else{
if(i > bel[l[j]] && i < bel[r[j]]){
if((x[j] << 1) <= R - tag){
for (register int k = tag + x[j];k > tag;k --)
if(rt[k]) merge(k, k + x[j]);
tag += x[j];
}
else{
for (register int k = R;k > x[j] + tag;k --)
if(rt[k]) merge(k, k - x[j]);
R = mn(R, tag + x[j]);
}
}
else{
if(i == bel[l[j]]){
rebuild(i);
for (register int k = l[j];k <= lst[bel[l[j]]];k ++)
if(a[k] > x[j]) a[k] -= x[j];
build(i);
}
else if(i == bel[r[j]]){
rebuild(i);
for (register int k = fst[bel[r[j]]];k <= r[j];k ++)
if(a[k] > x[j]) a[k] -= x[j];
build(i);
}
}
}
}
else{
if(bel[l[j]] == bel[r[j]]){
if(bel[l[j]] ^ i) continue;
for (register int k = l[j];k <= r[j];k ++)
if(val[find(k)] - tag == x[j]) ans[j] ++;
}
else{
if(x[j] + tag > tot) continue;
if(i > bel[l[j]] && i < bel[r[j]]) ans[j] += sz[x[j] + tag];
else{
if(i == bel[l[j]]){
for (register int k = l[j];k <= lst[bel[l[j]]];k ++)
if(val[find(k)] - tag == x[j]) ans[j] ++;
}
else if(i == bel[r[j]]){
for (register int k = fst[bel[r[j]]];k <= r[j];k ++)
if(val[find(k)] - tag == x[j]) ans[j] ++;
}
}
}
}
}
rebuild(i);
}
for (register int j = 1;j <= m;j ++)
if(opt[j] == 2) fprint(ans[j], 10);
}