社区讨论

60pts 李超线段树 WA 玄关

P5785[SDOI2012] 任务安排参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mln6efwy
此快照首次捕获于
2026/02/15 11:18
4 天前
此快照最后确认于
2026/02/19 13:10
2 小时前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
struct ppp{
	long long K,B;
}lines[300005];
#define get(kk,xx) (lines[kk].K * xx + lines[kk].B)
int n,s,t[300005],c[300005],cnt;
int tree[1200005];
long long dp[300005],sumt[300005],sumc[300005],qfr[300005],ys[300005];
unordered_map<int,int>mp;
#define mid ((l+r)>>1)
#define emp (l == r)
void insert(int x,int l,int r,int d){
	if(tree[x] == -1){
		tree[x] = d;
		return;
	}
	int l1 = tree[x],l2 = d;
	if(get(l1,ys[mid]) > get(l2,ys[mid])) swap(l1,l2);
	tree[x] = l1;
	if(emp || (get(l1,ys[l]) <= get(l2,ys[l]) && get(l1,ys[r]) <= get(l2,ys[r]))) return;
	if(get(l1,ys[l]) > get(l2,ys[l])) insert(x<<1,l,mid,l2);
	else insert(x<<1|1,mid+1,r,l2);
}
int ask(int x,int l,int r,int pos){
	if(emp) return tree[x];
	int ans = -1;
	if(pos <= mid) ans = ask(x<<1,l,mid,pos);
	else ans = ask(x<<1|1,mid+1,r,pos);
	if(ans == -1) return tree[x];
	if(tree[x] == -1) return ans;
	if(get(tree[x],ys[pos]) < get(ans,ys[pos])) return tree[x];
	else return ans;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin >> n >> s;
	for(int i = 1;i <= n;++i) cin >> t[i] >> c[i];
	for(int i = 1;i <= n;++i) sumt[i] = sumt[i-1] + t[i],sumc[i] = sumc[i-1] + c[i],qfr[i] = sumt[i];
	sort(qfr+1,qfr+n+1),mp[qfr[1]] = ++cnt;
	for(int i = 2;i <= n;++i) if(qfr[i] != qfr[i-1]) ++cnt,mp[qfr[i]] = cnt,ys[cnt] = qfr[i];
	for(int i = 1;i <= (n<<2);++i) tree[i] = -1;
	lines[0] = {0,0},insert(1,1,cnt,0);
	for(int i = 1;i <= n;++i){
		int from = ask(1,1,cnt,mp[sumt[i]]);
		dp[i] = get(from,sumt[i]) + s * sumc[n] + sumc[i] * sumt[i];
		lines[i] = {-sumc[i],dp[i] - s * sumc[i]},insert(1,1,cnt,i);
	}
	cout << dp[n];
	return 0;
}
感谢 QAQ

回复

1 条回复,欢迎继续交流。

正在加载回复...