爆
查看原帖
爆
817925
whileAK楼主2024/4/9 14:56

本蒟蒻在dp时,如果发现结果大于1e18,就返回1e18+10。因为如果最终的最小代价大于1e18,不会影响输出;如果最终的最小代价小于1e18,那最终的答案肯定不会从这转移,那这赋一个大点的值就好。可是WA了,30pts。有没有大佬解答QAQ

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void rd(int &p){
	p=0;char c=getchar();ll f=1;
	while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
	while(c>='0'&&c<='9')p=(p<<1)+(p<<3)+c-'0',c=getchar();
	p*=f;
}
void rdl(ll &p){
	p=0;char c=getchar();ll f=1;
	while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
	while(c>='0'&&c<='9')p=(p<<1)+(p<<3)+c-'0',c=getchar();
	p*=f;
}
const int N=1e5+50;
ll inf=1000000000000000010ll;
int t,n,L,k,p[N],tp,tl;
char c[N][35];
ll qp(ll x,int y){
    ll an(1);
    if(!x&&y)return 0ll;
    for(;y;y>>=1){
        if(y&1){
            if(an>(inf-10ll)/x)return inf;
            an*=x;
        }
        if(x>(inf-10ll)/x)x=inf;
        else x=x*x;
    }
    return an;
}
ll f[N],s[N];
struct sol{
    int l,r,pr;
}b[N];
ll val(int i,int j){
    f[n+1]=qp(1ll*abs(s[i]-s[j]-L+i-j-1),k);
    if(f[j]>(inf-10ll)-f[n+1])return inf;
    return f[j]+f[n+1];
}
int main(){
    rd(t);
    while(t--){
        rd(n),rd(L),rd(k);
        for(int i(1);i<=n;++i)scanf("%s",c[i]+1);
        for(int i(1);i<=n;++i){
            s[i]=1ll*strlen(c[i]+1)+s[i-1];
        }tp=tl=1;b[tp]=sol{1,n,0};
        for(int i(1),u,v,mid;i<=n;++i){
            p[i]=b[tl].pr;
            if(b[tl].l==b[tl].r)++tl;
            else ++b[tl].l;
            f[i]=val(i,p[i]);
            while(tl<=tp&&val(b[tp].l,b[tp].pr)>=val(b[tp].l,i))--tp;
            if(tl>tp){
                b[++tp]=sol{i+1,n,i};continue;
            }
            if(val(b[tp].r,b[tp].pr)<val(b[tp].r,i))u=b[tp].r+1;
            else{
                u=b[tp].l,v=b[tp].r;
                
                while(u<v){
                    mid=u+v>>1;
                    if(val(mid,b[tp].pr)>val(mid,i))v=mid;
                    else u=mid+1;
                }
                b[tp].r=u-1;
            }
            if(u<=n)b[++tp]=sol{u,n,i};
        }
        if(f[n]>inf-10ll)printf("Too hard to arrange\n");
        else{
            printf("%lld\n",f[n]);
            k=n;
            while(k){
                s[k]=-1;k=p[k];
            }
            for(int i(1);i<=n;++i){
                printf("%s",c[i]+1);
                if(s[i]==-1ll)printf("\n");
                else printf(" ");
            }
        }
        printf("--------------------");
        if(t)printf("\n");
    }
	return 0;
}
2024/4/9 14:56
加载中...