求助,分块 WA 80 pts
  • 板块P3863 序列
  • 楼主chlchl
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/1/12 20:32
  • 上次更新2023/10/24 04:32:09
查看原帖
求助,分块 WA 80 pts
363036
chlchl楼主2023/1/12 20:32

wtcl,每次都调不出来……

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 3e5 + 10;
const int M = 400 + 10;
int n, m, ans[N];
int tot, blk, bel[N], sp[M], tp[M];
ll tag[M];
struct event{
	int op, t;
	ll x;
};
struct element{
	ll val;
	int id;
	bool operator < (const element &p) const {
		if(val != p.val)
			return val < p.val;
		return id < p.id;
	}
} a[N];
vector<event> e[N];

void update(int p, ll x){//将区间加拆成两个后缀加 
    for(int i=sp[bel[p]];i<=tp[bel[p]];i++)
        if(a[i].id >= p)
            a[i].val += x;
    sort(a + sp[bel[p]], a + tp[bel[p]] + 1);
    for(int i=bel[p]+1;i<=tot;i++)
		tag[i] += x;
}

int query(int p, ll x){//前缀区间询问 
	int res = 0;
	for(int i=sp[bel[p]];i<=tp[bel[p]];i++)
		if(a[i].id <= p && a[i].val + tag[bel[i]] >= x)
			++res;
	for(int i=1;i<bel[p];i++)
	res += tp[i] - (lower_bound(a + sp[i], a + tp[i] + 1, ((element){x - tag[i], 0})) - a) + 1;
	return res;
}

int main(){
	memset(ans, -1, sizeof(ans));
	scanf("%d%d", &n, &m);
	++m;
	for(int i=1;i<=n;i++){
		ll x;
		scanf("%lld", &x);
		e[i].push_back((event){1, 1, x});
		e[i + 1].push_back((event){1, 1, -x}); 
	}
	tot = 333, blk = m / tot + (m % tot ? 1 : 0);
	for(int i=1;i<=m;i++)
		a[i] = (element){0, i}, bel[i] = (i - 1) / blk + 1;
	for(int i=1;i<=tot;i++)
		sp[i] = (i - 1) * blk + 1, tp[i] = i * blk;
	tp[tot] = m;
	
	for(int i=2,op,l,r;i<=m;i++){
		ll x;
		scanf("%d", &op);
		if(op == 1){
			scanf("%d%d%lld", &l, &r, &x);
			e[l].push_back((event){1, i, x});
			e[r + 1].push_back((event){1, i, -x});
		}
		else{
			scanf("%d%lld", &l, &x);
			e[l].push_back((event){2, i, x});
		}
	}
	for(int i=1;i<=n;i++){
		for(event q: e[i]){
			if(q.op == 1)
				update(q.t, q.x);
            else
				ans[q.t] = query(q.t - 1, q.x);
		}
	}
	for(int i=2;i<=m;i++)
		if(~ans[i])
			printf("%d\n", ans[i]);
	return 0;
}
2023/1/12 20:32
加载中...