社区讨论

萌新求助QAQ

P2305[NOI2014] 购票参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mi867jr3
此快照首次捕获于
2025/11/21 09:17
4 个月前
此快照最后确认于
2025/11/21 09:17
4 个月前
查看原帖
这题wsm不能和P3994 高速公路一样写呢。。
只是在队列上二分的时候多判断 一个lv啊QAQ
但是貌似只有16分(过第八个点。
一开始以为是精度问题,改成long long之后错误信息变了,但还是只有16分(awsl
下面是代码,
CPP
#include<cstdio>
const int MaxN=2e5,MaxM=MaxN-1;
template<typename integer>inline const void read(integer &ans)
{
    ans=0;
    char c=getchar();
    while(c<'0'||c>'9')
        c=getchar();
    while(c>='0'&&c<='9')
        ans=ans*10+c-48,c=getchar();
    return; 
}
int head[MaxN+1],to[MaxM+1],w[MaxM+1],next[MaxM+1],tot=1;
inline const void add(const int &x,const int &y,const int &z)
{
    to[tot]=y,w[tot]=z,next[tot]=head[x],head[x]=tot++;
    return;
}
int n,m,f[MaxN+1];
long long s[MaxN+1],p[MaxN+1],q[MaxN+1],lg[MaxN+1],dis[MaxN+1];
int que[MaxN+1],h=1,t=0;
long long fun[MaxN+1];
inline const double slope(int i,int j)
{
    return (double)(fun[j]-fun[i])/(dis[j]-dis[i]);
}
int l,r,mid;
inline const void DP(int x) 
{
    int i;
    int rh=h,rt=t;
    l=h,r=t;
//	printf("x:%d h:%d t:%d\n---------------------------------\n",x,h,t);
//	for(i=h;i<t;i++)
//		printf("\tx:%d dis:%d f:%d slope:%lf\n",que[i],dis[que[i]],fun[que[i]],slope(que[i],que[i+1]));
//	if(h<=t)
//		printf("\tx:%d dis:%d f:%d\n",que[t],dis[que[t]],fun[que[t]]);
//	putchar('\n');
    while(l<r)
    {
        mid=l+r>>1;
        if((mid==t||slope(que[mid],que[mid+1])>=p[x])&&dis[x]-dis[que[mid]]<=lg[x])
            r=mid;
        else
            l=mid+1;
    }
    h=r;
//	printf("x:%d dis[x]-dis[h]:%d\n",x,dis[x]-dis[que[h]]);
    fun[x]=fun[que[h]]+q[x]+p[x]*(dis[x]-dis[que[h]]);
    l=h,r=t;
    while(l<r)
    {
        mid=l+r+1>>1;
        if(mid==h||slope(que[mid-1],que[mid])<=slope(que[mid],x))
            l=mid;
        else
            r=mid-1;
    }
//	printf("x:%d\n",x);
    int rp=r+1,rq=que[r+1];
    t=r,que[++t]=x;
    for(i=head[x];i;i=next[i])
        dis[to[i]]=dis[x]+w[i],DP(to[i]);
    que[rp]=rq,h=rh,t=rt;
    return;
}
int main()
{
    int i;
    read(n),read(m);
    for(i=2;i<=n;i++)
        read(f[i]),read(s[i]),read(p[i]),read(q[i]),read(lg[i]),add(f[i],i,s[i]);
    que[++t]=1;
    for(i=head[1];i;i=next[i])
        dis[to[i]]=w[i],DP(to[i]);
    //DP(1);
    for(i=2;i<=n;i++)
        printf("%lld\n",fun[i]);
    return 0;
}

回复

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

正在加载回复...