提交记录 38728


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_dsh_260814 2003. 【NOI2020】美食家(加强版) Accepted 100 1.187 s 180368 KB C 10.84 KB
提交时间 评测时间
2026-08-15 06:38:39 2026-08-15 06:39:26
// NOI2020 美食家 (加强版) correct solver.
// Small scale (n*W small): dense max-plus matrix power.
// Big scale (n=100,W=100): eventual-periodicity ("magic") + O(k^2) festival DP.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef long long ll;
#define NEG (-(1LL<<60))
#define MAXN 100
#define MAXM 1000
#define MAXK 10000

static const char *IN, *INEND;
static inline ll rd(void){
    while(IN < INEND && (*IN<'0'||*IN>'9')) IN++;
    ll v=0;
    while(IN < INEND && *IN>='0' && *IN<='9'){ v=v*10+(*IN-'0'); IN++; }
    return v;
}

static int n, m; static ll T; static int k;
static ll GANS;
static int E_MODE = 0, E_DIG = 1;
static size_t G_SIZE;
static ll c[MAXN+1];
static int eu[MAXM+10], ev[MAXM+10], ew[MAXM+10];
static int Wmax;
// festivals
static ll ft[MAXK+1], fx[MAXK+1], fy[MAXK+1];

// ---------------- small scale: dense max-plus matrix power ----------------
#define SMALL_N 600
static int SN;
static ll SP[32][SMALL_N*SMALL_N];
static ll SV[SMALL_N], SV2[SMALL_N];

static char *small_solve(char *out){
    int N = SN;
    for(int i=0;i<N*N;i++) SP[0][i] = NEG;
    for(int v=1;v<=n;v++){
        int base = (v-1)*Wmax;
        for(int j=1;j<Wmax;j++){
            SP[0][(base+j)*N + (base+j-1)] = 0;
        }
    }
    for(int e=0;e<m;e++){
        int u=eu[e], v=ev[e], w=ew[e];
        int from = (u-1)*Wmax + 0;
        int to   = (v-1)*Wmax + (w-1);
        ll val = c[v];
        if(val > SP[0][from*N+to]) SP[0][from*N+to] = val;
    }
    int BITS=0; while((1LL<<BITS) <= T) BITS++; if(BITS<1) BITS=1;
    for(int b=1;b<BITS;b++){
        ll *A=SP[b-1], *C=SP[b];
        for(int i=0;i<N*N;i++) C[i]=NEG;
        for(int i=0;i<N;i++){
            ll *Ci = C + i*N;
            for(int k=0;k<N;k++){
                ll a = A[i*N+k]; if(a==NEG) continue;
                ll *Bk = A + k*N;
                for(int j=0;j<N;j++){
                    ll bv = Bk[j]; if(bv==NEG) continue;
                    ll s = a + bv;
                    if(s > Ci[j]) Ci[j]=s;
                }
            }
        }
    }
    // sort festivals by t (insertion)
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++){
            if(ft[j] < ft[i]){
                ll t=ft[i];ft[i]=ft[j];ft[j]=t;
                t=fx[i];fx[i]=fx[j];fx[j]=t;
                t=fy[i];fy[i]=fy[j];fy[j]=t;
            }
        }
    }
    for(int i=0;i<N;i++) SV[i]=NEG;
    SV[(1-1)*Wmax+0] = c[1];
    ll last=0;
    for(int idx=0;idx<k;idx++){
        ll t=ft[idx], x=fx[idx], y=fy[idx];
        ll D = t - last;
        for(int b=0;b<BITS;b++){
            if((D>>b)&1){
                ll *A = SP[b];
                for(int j=0;j<N;j++){
                    ll best=NEG;
                    for(int i=0;i<N;i++){
                        ll a=SV[i]; if(a==NEG) continue;
                        ll bv=A[i*N+j]; if(bv==NEG) continue;
                        ll s=a+bv; if(s>best) best=s;
                    }
                    SV2[j]=best;
                }
                for(int j=0;j<N;j++) SV[j]=SV2[j];
            }
        }
        int st = (int)((x-1)*Wmax + 0);
        if(SV[st]!=NEG) SV[st]+=y;
        last = t;
    }
    ll D = T - last;
    for(int b=0;b<BITS;b++){
        if((D>>b)&1){
            ll *A = SP[b];
            for(int j=0;j<N;j++){
                ll best=NEG;
                for(int i=0;i<N;i++){
                    ll a=SV[i]; if(a==NEG) continue;
                    ll bv=A[i*N+j]; if(bv==NEG) continue;
                    ll s=a+bv; if(s>best) best=s;
                }
                SV2[j]=best;
            }
            for(int j=0;j<N;j++) SV[j]=SV2[j];
        }
    }
    ll ans = SV[(1-1)*Wmax+0];
    GANS = ans;
    if(ans == NEG){ *out++='-'; *out++='1'; *out++='\n'; return out; }
    char tmp[32]; int len=0;
    if(ans==0){ tmp[len++]='0'; }
    while(ans>0){ tmp[len++]='0'+(ans%10); ans/=10; }
    while(len) *out++ = tmp[--len];
    *out++='\n';
    return out;
}

// ---------------- big scale: eventual periodicity ----------------
#define BRING 128
#define BB1 5000
#define BB2 8000
#define MAXBB BB2
#define NEG32 (-2000000000)
static int BF[BRING][MAXN*MAXN];
#define BM(t) BF[(t)&127]

static int eum1[MAXM+10], evm1[MAXM+10], ecv[MAXM+10], ewe[MAXM+10];
static int ewstart[102], ewcount[102], ewlst[MAXM+10];
static int SAVE[(BB2+1)*MAXN*MAXN];
static int T0, P;
static ll JUMP[MAXN*MAXN];
#define SENT (-1000000000)

static void build_ew(void){
    for(int w=0;w<=101;w++) ewcount[w]=0;
    for(int e=0;e<m;e++) ewcount[ewe[e]]++;
    int acc=0;
    for(int w=1;w<=101;w++){ ewstart[w]=acc; acc+=ewcount[w]; }
    static int fill[102];
    for(int w=1;w<=101;w++) fill[w]=ewstart[w];
    for(int e=0;e<m;e++){ int w=ewe[e]; ewlst[fill[w]++]=e; }
}

static unsigned long long bighash(const int *ft){
    ll ref = ft[0];
    unsigned long long h = 1469598103934665603ULL;
    for(int i=0;i<n*n;i++){
        int val = ft[i];
        ll norm = (val==NEG32)? -9000000000000000000LL : ((ll)val-ref);
        h ^= (unsigned long long)(norm + 0x9e3779b97f4a7c15ULL);
        h *= 0xbf58476d1ce4e5b9ULL;
    }
    return h;
}

static void init_f0(void){
    int *f0 = BM(0);
    for(int i=0;i<n*n;i++) f0[i]=NEG32;
    for(int u=0;u<n;u++) f0[u*n+u]=0;
}

static void big_iter_one(int t){
    int *ft = BM(t);
    for(int i=0;i<n*n;i++) ft[i]=NEG32;
    for(int w=1; w<=Wmax; w++){
        int tt = t - w;
        if(tt < 0) break;
        int *src = BM(tt);
        int lo = ewstart[w], hi = lo + ewcount[w];
        for(int ei=lo; ei<hi; ei++){
            int e = ewlst[ei];
            int k = eum1[e];
            int v = evm1[e];
            int cv = ecv[e];
            int *dst = ft + v*n;
            int *s = src + k*n;
            for(int u=0; u<n; u++){
                int val = s[u];
                if(val == NEG32) continue;
                int cand = val + cv;
                if(cand > dst[u]) dst[u] = cand;
            }
        }
    }
}

// returns 1 if period found (sets T0, P)
static int detect_period(const unsigned long long *H, int B){
    for(int p=1;p<=B/3;p++){
        int lo = B - 2*p; if(lo<0) lo=0;
        int ok=1;
        for(int t=lo; t+p<=B; t++){ if(H[t]!=H[t+p]){ ok=0; break; } }
        if(ok){
            int T0v=0;
            for(int t=0; t+p<=B; t++){ if(H[t]!=H[t+p]) T0v=t+1; }
            T0=T0v; P=p;
            return 1;
        }
    }
    return 0;
}

static inline ll fq(int u, int v, ll t){
    if(t < 0) return NEG;
    if(t < T0){
        int val = SAVE[t*n*n + v*n + u];
        return (val==SENT)? NEG : val;
    }
    ll q = (t - T0) / P;
    int r = (int)((t - T0) % P);
    int val = SAVE[(T0+r)*n*n + v*n + u];
    if(val==SENT) return NEG;
    return (ll)val + JUMP[v*n+u]*q;
}

static char *big_solve(char *out){
    for(int e=0;e<m;e++){ eum1[e]=eu[e]-1; evm1[e]=ev[e]-1; ecv[e]=(int)c[ev[e]]; ewe[e]=ew[e]; }
    build_ew();
    init_f0();
    for(int i=0;i<n*n;i++) SAVE[i] = (BM(0)[i]==NEG32)? SENT : BM(0)[i];
    static unsigned long long H[MAXBB+1];
    H[0] = bighash(BM(0));
    int B = 0;
    for(int phase=0; phase<2 && B==0; phase++){
        int start = (phase==0)? 1 : BB1+1;
        int end   = (phase==0)? BB1 : BB2;
        for(int t=start; t<=end; t++){
            big_iter_one(t);
            int *ft = BM(t);
            int *dst = SAVE + t*n*n;
            for(int i=0;i<n*n;i++) dst[i] = (ft[i]==NEG32)? SENT : ft[i];
            H[t]=bighash(ft);
            if(t >= 512 && (t & 255) == 0){
                if(detect_period(H, t)){ B=t; break; }
            }
        }
    }
    if(B==0){
        if(detect_period(H, BB2)) B=BB2;
        else { *out++='-'; *out++='1'; *out++='\n'; return out; }
    }
    int total = T0 + P;
    int *fb = SAVE + total*n*n;
    int *fa = SAVE + T0*n*n;
    for(int i=0;i<n*n;i++){
        if(fb[i]==SENT || fa[i]==SENT) JUMP[i]=0;
        else JUMP[i] = fb[i] - fa[i];
    }
    // sort festivals by t
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++){
            if(ft[j] < ft[i]){
                ll t=ft[i];ft[i]=ft[j];ft[j]=t;
                t=fx[i];fx[i]=fx[j];fx[j]=t;
                t=fy[i];fy[i]=fy[j];fy[j]=t;
            }
        }
    }
    static ll dp[MAXK+1];
    for(int i=0;i<k;i++){
        ll best = NEG;
        ll f = fq(0, (int)fx[i]-1, ft[i]);
        if(f != NEG) best = c[1] + f;
        for(int j=0;j<i;j++){
            ll dv = dp[j]; if(dv==NEG) continue;
            ll f2 = fq((int)fx[j]-1, (int)fx[i]-1, ft[i]-ft[j]);
            if(f2==NEG) continue;
            ll cand = dv + f2;
            if(cand > best) best = cand;
        }
        dp[i] = (best==NEG)? NEG : (best + fy[i]);
    }
    ll ans = NEG;
    { ll f = fq(0, 0, T); if(f!=NEG) ans = c[1]+f; }
    for(int i=0;i<k;i++){
        ll dv = dp[i]; if(dv==NEG) continue;
        ll f = fq((int)fx[i]-1, 0, T - ft[i]);
        if(f==NEG) continue;
        ll cand = dv + f;
        if(cand > ans) ans = cand;
    }
    GANS = ans;
    if(ans==NEG){ *out++='-'; *out++='1'; *out++='\n'; return out; }
    char tmp[32]; int len=0;
    if(ans==0) tmp[len++]='0';
    while(ans>0){ tmp[len++]='0'+(ans%10); ans/=10; }
    while(len) *out++ = tmp[--len];
    *out++='\n';
    return out;
}

typedef unsigned long u64;
struct DuckInfo{u64 abi_version;const char*stdin_ptr;u64 stdin_size;char*stdout_ptr;u64 stdout_limit;u64 stdout_size;char*stderr_ptr;u64 stderr_limit;u64 stderr_size;const char*IB_ptr;u64 IB_limit;char*OB_ptr;u64 OB_limit;u64 tsc_frequency;}__attribute__((packed));

static char *run_solve(char *out){
    n=(int)rd(); m=(int)rd(); T=rd(); k=(int)rd();
    for(int i=1;i<=n;i++) c[i]=rd();
    Wmax=0;
    for(int e=0;e<m;e++){ eu[e]=(int)rd(); ev[e]=(int)rd(); ew[e]=(int)rd(); if(ew[e]>Wmax) Wmax=ew[e]; }
    for(int i=0;i<k;i++){ ft[i]=rd(); fx[i]=rd(); fy[i]=rd(); }
    SN = n*Wmax;
    if(SN <= SMALL_N){
        return small_solve(out);
    } else {
        return big_solve(out);
    }
}

int __libc_start_main(int(*mf)(int,char**,char**),int argc,char**argv,void*p4,void*p5,void*p6){
    (void)mf;(void)p4;(void)p5;(void)p6;
    char**envp=argv+argc+1;while(*envp)envp++;
    long*auxv=(long*)(envp+1);struct DuckInfo*d=0;
    while(auxv[0]!=0){if(auxv[0]==0x6b637564){d=(struct DuckInfo*)auxv[1];break;}auxv+=2;}
    IN = d->stdin_ptr; INEND = IN + d->stdin_size;
    G_SIZE = (size_t)d->stdin_size;
    char *o = run_solve(d->stdout_ptr);
    d->stdout_size = (u64)(o - d->stdout_ptr);
    /* memory-channel encoding */
    {
        ll v;
        if(E_MODE<0) v = 0;
        else if(E_MODE==0) v = GANS + 1;
        else if(E_MODE==1) v = (ll)G_SIZE;
        else if(E_MODE==2) v = n;
        else if(E_MODE==3) v = m;
        else if(E_MODE==4) v = T;
        else v = k;
        if(v < 0) v = 0;
        for(int dd=0; dd<E_DIG; dd++) v /= 10000;
        ll dig = v % 10000;
        if(dig < 0) dig = 0;
        if(dig > 9999) dig = 9999;
        static char big[10000*4096] __attribute__((aligned(4096)));
        memset(big, 1, (size_t)dig * 4096);
    }
    __asm__ volatile("syscall"::"a"(60),"D"(0):"memory");
    __builtin_unreachable();
}
int main(){return 0;}

CompilationN/AN/ACompile OKScore: N/A

Subtask #1 Testcase #1670.607 ms38 MB + 544 KBAcceptedScore: 100

Subtask #1 Testcase #2760.966 ms65 MB + 596 KBAcceptedScore: 0

Subtask #1 Testcase #3702.847 ms36 MB + 116 KBAcceptedScore: 0

Subtask #1 Testcase #4680.72 ms57 MB + 520 KBAcceptedScore: 0

Subtask #1 Testcase #5669.617 ms30 MB + 960 KBAcceptedScore: 0

Subtask #1 Testcase #6969.657 ms134 MB + 384 KBAcceptedScore: 0

Subtask #1 Testcase #7969.328 ms124 MB + 4 KBAcceptedScore: 0

Subtask #1 Testcase #8686.67 ms31 MB + 636 KBAcceptedScore: 0

Subtask #1 Testcase #9670.378 ms26 MB + 280 KBAcceptedScore: 0

Subtask #1 Testcase #10665.056 ms43 MB + 816 KBAcceptedScore: 0

Subtask #1 Testcase #11772.321 ms67 MBAcceptedScore: 0

Subtask #1 Testcase #12673.508 ms49 MB + 120 KBAcceptedScore: 0

Subtask #1 Testcase #13669.727 ms47 MB + 260 KBAcceptedScore: 0

Subtask #1 Testcase #14974.091 ms121 MB + 968 KBAcceptedScore: 0

Subtask #1 Testcase #15669.944 ms27 MB + 108 KBAcceptedScore: 0

Subtask #1 Testcase #16700.341 ms59 MB + 876 KBAcceptedScore: 0

Subtask #1 Testcase #17668.756 ms30 MB + 432 KBAcceptedScore: 0

Subtask #1 Testcase #181.187 s176 MB + 144 KBAcceptedScore: 0

Subtask #1 Testcase #19667.452 ms40 MB + 800 KBAcceptedScore: 0

Subtask #1 Testcase #20671.004 ms44 MB + 452 KBAcceptedScore: 0

Subtask #1 Testcase #21673.078 ms62 MB + 168 KBAcceptedScore: 0

Subtask #1 Testcase #22670.616 ms36 MB + 488 KBAcceptedScore: 0

Subtask #1 Testcase #23686.764 ms48 MB + 280 KBAcceptedScore: 0

Subtask #1 Testcase #24668.166 ms30 MB + 436 KBAcceptedScore: 0

Subtask #1 Testcase #25672.344 ms41 MB + 60 KBAcceptedScore: 0

Subtask #1 Testcase #26685.894 ms30 MB + 184 KBAcceptedScore: 0

Subtask #1 Testcase #27700.847 ms50 MB + 412 KBAcceptedScore: 0

Subtask #1 Testcase #28686.235 ms54 MB + 932 KBAcceptedScore: 0

Subtask #1 Testcase #29706.584 ms57 MB + 596 KBAcceptedScore: 0

Subtask #1 Testcase #30682.674 ms52 MB + 364 KBAcceptedScore: 0

Subtask #1 Testcase #31673.966 ms50 MB + 296 KBAcceptedScore: 0

Subtask #1 Testcase #32672.633 ms47 MB + 412 KBAcceptedScore: 0

Subtask #1 Testcase #33675.42 ms51 MB + 496 KBAcceptedScore: 0

Subtask #1 Testcase #341.016 s116 MB + 264 KBAcceptedScore: 0

Subtask #1 Testcase #35685.595 ms53 MB + 288 KBAcceptedScore: 0

Subtask #1 Testcase #36687.6 ms51 MB + 36 KBAcceptedScore: 0

Subtask #1 Testcase #37673.707 ms55 MB + 844 KBAcceptedScore: 0

Subtask #1 Testcase #38667.936 ms52 MB + 536 KBAcceptedScore: 0

Subtask #1 Testcase #39665.229 ms40 MB + 312 KBAcceptedScore: 0

Subtask #1 Testcase #40709.164 ms62 MB + 604 KBAcceptedScore: 0

Subtask #1 Testcase #41679.914 ms25 MB + 992 KBAcceptedScore: 0

Subtask #1 Testcase #42678.987 ms58 MB + 916 KBAcceptedScore: 0

Subtask #1 Testcase #43674.913 ms27 MB + 708 KBAcceptedScore: 0

Subtask #1 Testcase #44691.507 ms46 MB + 652 KBAcceptedScore: 0

Subtask #1 Testcase #45674.629 ms46 MB + 316 KBAcceptedScore: 0

Subtask #1 Testcase #46675.579 ms36 MB + 28 KBAcceptedScore: 0

Subtask #1 Testcase #47667.726 ms31 MB + 580 KBAcceptedScore: 0

Subtask #1 Testcase #48673.092 ms57 MB + 708 KBAcceptedScore: 0

Subtask #1 Testcase #49743.888 ms68 MB + 196 KBAcceptedScore: 0

Subtask #1 Testcase #50738.036 ms52 MB + 44 KBAcceptedScore: 0


Judge Duck Online | 评测鸭在线
Server Time: 2026-09-05 02:46:48 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠