40分求调
查看原帖
40分求调
773878
xukehg楼主2024/9/18 14:17

rt,不知道是常数太大还是怎么回事一直TLE。

#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 5;
inline int read() {
	int x=0,f=1;
	char ch=getchar();
	while (ch<'0' || ch>'9') {
		if (ch=='-')f=-1;
		ch=getchar();
	}
	while ('0'<=ch && ch<='9') {
		x=(x<<3)+(x<<1)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
inline void write(int x) {
	static int sta[35];
	int top = 0;
	do {
		sta[top++] = x % 10,x /= 10;
	} while (x);
	while (top) putchar(sta[--top] + 48);
}
namespace Chain_forward_star{
	int tot = 0;
	struct node{
		int to;
		int nxt;
	}edge[N << 1];
   	int head[N];
	void add(int u,int v){
		edge[++tot].to = v;
		edge[tot].nxt = head[u];
		head[u] = tot;
	}
}
using namespace Chain_forward_star;
int n,k,nums[N],d[N],c[N],s[N],w[N],st[N],ed[N];
int my_left[N << 2],my_right[N << 2];
int sum[N << 2],lazy[N << 2];
inline void push_up(int u){
	sum[u] = min(sum[u << 1],sum[u << 1 | 1]);
}
inline void update(int x,int p){
	sum[x] += p;
	lazy[x] += p;
}
inline void push_down(int x){
	if (lazy[x]){
		update(x << 1,lazy[x]);
		update(x << 1 | 1,lazy[x]);
		lazy[x] = 0;
	}
}
inline void init(int l,int r,int u){
	my_left[u] = l;
	my_right[u] = r;
	if (my_left[u] == my_right[u]){
		return;
	}
	int mid = (l + r) >> 1;
	init(l,mid,u << 1);
	init(mid + 1,r,u << 1 | 1);
	push_up(u);
}
inline void build(int l,int r,int u){
	lazy[u] = 0;
	if (my_left[u] == my_right[u]){
		sum[u] = nums[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l,mid,u << 1);
	build(mid + 1,r,u << 1 | 1);
	push_up(u);
}
inline int query(int u,int l,int r){
	if (my_left[u] == my_right[u]) return sum[u];
	push_down(u);
	int mid = (my_left[u] + my_right[u]) >> 1;
	if (r <= mid) return query(u << 1,l,r);
    else if (l > mid) return query(u << 1 | 1,l,r);
    else return min(query(u << 1,l,mid),query(u << 1 | 1,mid + 1,r));
}
inline void modify(int u,int l,int r,int p){
	if (my_left[u] == my_right[u]){
		update(u,p);
		return;
	}
	push_down(u);
	int mid = (my_left[u] + my_right[u]) >> 1;
	if (r <= mid) modify(u << 1,l,r,p);
	else if (l > mid) modify(u << 1 | 1,l,r,p);
	else{
		modify(u << 1,l,mid,p);
		modify(u << 1 | 1,mid + 1,r,p);
	}
	push_up(u);
}
int main(){
	n = read(),k = read();k++;
	for (register int i = 2;i <= n;i++) d[i] = read();
	for (register int i = 1;i <= n;i++) c[i] = read();
	for (register int i = 1;i <= n;i++) s[i] = read();
	for (register int i = 1;i <= n;i++) w[i] = read();
	d[++n] = 1e9 + 7,w[n] = 1e9 + 7;
	for (register int i = 1;i <= n;i++){
		st[i] = lower_bound(d + 1,d + 1 + n,d[i] - s[i]) - d;
		ed[i] = lower_bound(d + 1,d + 1 + n,d[i] + s[i]) - d;
		if (d[ed[i]] > d[i] + s[i]) ed[i]--;
		add(ed[i],i);
	}
	int res = 0,ans = 0;
	for (register int i = 1;i <= n;i++){
		nums[i] = res + c[i];
		for (int xx = head[i];xx;xx = edge[xx].nxt) res += w[edge[xx].to];
	}
	ans = nums[n];
	init(1,n,1);
	for (register int i = 2;i <= k;i++){
		build(1,n,1);
		for (register int j = 1;j <= n;j++){
			nums[j] = (j > (i - 1) ? query(1,i - 1,j - 1) : 0) + c[j];
			for (register int xx = head[j];xx;xx = edge[xx].nxt){
				if (st[edge[xx].to] > 1) modify(1,1,st[edge[xx].to] - 1,w[edge[xx].to]);				
			}
		}
		ans = min(ans,nums[n]);
	}
	write(ans);
}
2024/9/18 14:17
加载中...