社区讨论
84分求调,悬赏关注
P7990[USACO21DEC] Closest Cow Wins S参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mlt5asc7
- 此快照首次捕获于
- 2026/02/19 15:34 3 周前
- 此快照最后确认于
- 2026/02/22 22:05 2 周前
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
map<int,int> mp;
int k2,k=0,m,n,p[1000005],q[1000005],d[1000005],lsh[1000005],tot=0,b[1000005];
struct A {
int l,r,w;
} a[1000005];
bool cmp(A a,A b) {
return a.l<b.l;
}
struct B {
int sz,wz;
};
bool operator <(B x,B y){
return x.sz<y.sz;
}
struct C {
int l,r,lz;
B mes;
} tr[4000005];
void makelazy(int p,int x) {
tr[p].lz+=x;
tr[p].mes.sz+=x;
}
void pushup(int p) {
tr[p].mes=max(tr[p<<1].mes,tr[p<<1|1].mes);
}
void pushdown(int p) {
makelazy(p<<1,tr[p].lz);
makelazy(p<<1|1,tr[p].lz);
tr[p].lz=0;
}
void build(int p,int l,int r) {
tr[p].l=l,tr[p].r=r,tr[p].lz=0;
if(l==r) {
tr[p].mes.sz=0,tr[p].mes.wz=l;
return;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void change(int p,int l,int r,int k) {
if(l<=tr[p].l&&tr[p].r<=r) {
makelazy(p,k);
return;
}
if(tr[p].l>r||tr[p].r<l)return;
pushdown(p);
change(p<<1,l,r,k);
change(p<<1|1,l,r,k);
pushup(p);
}
B search(int p,int l,int r) {
if(l<=tr[p].l&&tr[p].r<=r)return tr[p].mes;
if(tr[p].l>r||tr[p].r<l)return {(int)-1e18,(int)-1e18};
pushdown(p);
return max(search(p<<1,l,r),search(p<<1|1,l,r));
}
struct D {
int wz,bh;
};
bool operator <(D x,D y) {
if(x.wz!=y.wz)return x.wz<y.wz;
else return a[x.bh].l<a[y.bh].l;
}
struct E {
int wz,bh;
};
bool operator <(E x,E y) {
if(x.wz!=y.wz)return x.wz<y.wz;
else return a[x.bh].r<a[y.bh].r;
}
set<D> s1;
set<E> s2;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>k2>>m>>n;
for(int i=1; i<=k2; i++) {
int x,y;
cin>>x>>y;
if(!mp[x])mp[x]=++k,p[mp[x]]=x;
q[mp[x]]+=y;
}
for(int i=1; i<=m; i++)cin>>d[i];
sort(d+1,d+m+1);
d[0]=-1e18,d[m+1]=1e18;
for(int i=1; i<=k; i++) {
int x=min(d[lower_bound(d+1,d+m+1,p[i])-d]-p[i],p[i]-d[upper_bound(d+1,d+m+1,p[i])-d-1]);
a[i].l=p[i]-x+1,a[i].r=p[i]+x-1,a[i].w=q[i];
lsh[++tot]=a[i].l,lsh[++tot]=a[i].r;
}
sort(lsh+1,lsh+tot+1);
tot=unique(lsh+1,lsh+tot+1)-lsh-1;
build(1,1,tot);
for(int i=1; i<=k; i++) {
a[i].l=lower_bound(lsh+1,lsh+tot+1,a[i].l)-lsh,a[i].r=lower_bound(lsh+1,lsh+tot+1,a[i].r)-lsh;
if(a[i].l>a[i].r)continue;
change(1,a[i].l,a[i].r,a[i].w);
s1.insert({a[i].r,i});
s2.insert({a[i].l,i});
}
a[k+1].l=-1e18,a[k+1].r=1e18;
int ans=0;
for(int i=1; i<=n; i++) {
B x=search(1,1,tot);
if(x.sz==-1e18)break;
ans+=x.sz;
auto it1=s1.lower_bound({x.wz,k+1});
auto it2=s2.upper_bound({x.wz,k+1});
while(it1!=s1.end()&&a[it1->bh].l<=x.wz)change(1,a[it1->bh].l,a[it1->bh].r,-a[it1->bh].w*(1-b[it1->bh])),b[it1->bh]=1,it1++;
while(it2!=s2.begin()&&a[(--it2)->bh].r>=x.wz)change(1,a[it2->bh].l,a[it2->bh].r,-a[it2->bh].w*(1-b[it2->bh])),b[it2->bh]=1;
}
cout<<ans;
return 0;
}
离散化后,线段树维护区间最大值,每回选择所得最大的位置。由于区间相互不严格包含(只有端点可能重合),使用 set 维护区间,每回在线段树上删除包含已经选了的这个位置的区间的贡献。只有84分,WA了9,12,13,17。
回复
共 0 条回复,欢迎继续交流。
正在加载回复...