题解:P12027 [USACO25OPEN] Ski Slope S
题目传送门
注意到 \(c\le10\),所以我们想到可以用 \(g_{i,j}\) 表示从 \(i\) 出发滑到 \(1\) 的路径上,难度为第 \(j\) 大的值为多少,同时用 \(val_i\) 记录从 \(i\) 到 \(1\) 的路径的快乐值之和。
考虑怎么计算这个 \(g_{i,j}\),我们可以先把路径按 \(p_i\) 从小到大排,这样就可以从小到大处理。怎么维护前 \(11\) 大呢,可以直接暴力,每次排序后,判断一下最小值有没有比新加入的路径的难度值小,如果要小的话,就把最小值赋值为新的难度值。
for(int i=1;i<=n;i++){
ll now=s[i].id;
g[now].val+=s[i].e+g[s[i].p].val;
for(int j=1;j<=11;j++)g[now].dis[j]=g[s[i].p].dis[j];
sort(g[now].dis+1,g[now].dis+11+1,cmp1);
if(g[now].dis[11]<s[i].d)g[now].dis[11]=s[i].d;
sort(g[now].dis+1,g[now].dis+11+1,cmp1);
}
那么,处理好这个有什么用呢。我们先考虑暴力该怎么做,因为每个朋友有一个技能水平 \(s_j\) 和勇气值 \(c_j\),也就是说这个朋友最多可以经过有 \(c_j\) 个难度值大于 \(s_j\) 的路径。也就是 \(g_{i,c_j+1}\le s_j\)。
现在考虑如何优化,容易发现每次比对都只会比对第 \(c_j+1\) 大的难度值,所以我们可以把从 \(1\) 到 \(n\) 的前 \(11\) 大的难度值提出来,成为一个二维数组,\(d_{i,j}\) 就表示在难度第 \(i\) 大的数组里的第 \(j\) 条路径的值。我们再对这些数组进行降序排序,并且求出后缀 \(\max\),那么最后的答案就是在 \(d_{c_j+1}\) 中二分找到第一个大于等于 \(s_j\) 的位置 \(k\),那么答案就是 \(sum_{c_j+1,k}\)。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=101010;
ll n,a,b,m,ans,sum[15][N];
struct tt{
ll p,d,e,id;
}s[N];
struct gg{
ll val,dis[15];
}g[N];
struct cc{
ll num,id;
}c[15][N];
bool cmp(tt a,tt b){return a.p<b.p;}
bool cmp1(ll a,ll b){return a>b;}
bool cmpc(cc a,cc b){return a.num<b.num;}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<n;i++)cin>>s[i].p>>s[i].d>>s[i].e,s[i].id=i,s[i].p--;
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++){
ll now=s[i].id;
g[now].val+=s[i].e+g[s[i].p].val;
for(int j=1;j<=11;j++)g[now].dis[j]=g[s[i].p].dis[j];
sort(g[now].dis+1,g[now].dis+11+1,cmp1);
if(g[now].dis[11]<s[i].d)g[now].dis[11]=s[i].d;
sort(g[now].dis+1,g[now].dis+11+1,cmp1);
}
for(int i=1;i<=11;i++){
for(int j=1;j<=n;j++)c[i][j].num=g[j].dis[i],c[i][j].id=j;
sort(c[i]+1,c[i]+n+1,cmpc);
for(int j=1;j<=n;j++)sum[i][j]=max(sum[i][j-1],g[c[i][j].id].val);
}
cin>>m;
while(m--){
ans=0;
cin>>a>>b;
ll l=1,r=n,ans=0;
while(l<=r){
ll mid=l+r>>1;
if(a>=c[b+1][mid].num)ans=max(ans,sum[b+1][mid]),l=mid+1;
else r=mid-1;
}
cout<<ans<<"\n";
}
return 0;
}
完结撒花

浙公网安备 33010602011771号