8.23NOIP Day9模拟赛

T1

诈骗题,直接跑dij改一下就秒了

#include<bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
int n,m,s,t,dis[N];
struct Ty{int t,s,e;}x[N];
vector<pair<int,int> >y[N];
priority_queue<pair<int,int> >q;
void dij(){
    for(int i=1;i<=n;i++)dis[i]=1e18;
    dis[s]=0;
    q.push(make_pair(0,s));
    while(!q.empty()){
        int u=q.top().second,v=-q.top().first;
        q.pop();
        if(v%x[u].t<x[u].s)v+=x[u].s-v%x[u].t;
        else if(v%x[u].t>x[u].e)v+=x[u].s+x[u].t-v%x[u].t;
        for(int i=0;i<y[u].size();i++)if(v+y[u][i].second<dis[y[u][i].first]){
            dis[y[u][i].first]=v+y[u][i].second;
            q.push(make_pair(-dis[y[u][i].first],y[u][i].first));
        }
    }
    return;
}
signed main(){
    scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
    for(int i=1;i<=n;i++)scanf("%lld%lld%lld",&x[i].t,&x[i].s,&x[i].e);
    for(int i=1;i<=m;i++){
        int u,v,w;
        scanf("%lld%lld%lld",&u,&v,&w);
        y[u].push_back(make_pair(v,w));
        y[v].push_back(make_pair(u,w));
    }
    dij();
    printf("%lld\n",dis[t]);
    return 0;
}

T2

考虑把填数转化为从列向行连边,易证连 \((i,j),(i+x,j+y)\) 对于连 \((i,j+y),(j,i+x)\) 是不劣的,然后就双指针秒了

#include<bits/stdc++.h>
#define int long long
#define N 1000005
using namespace std;
int x[N],y[N];
signed main(){
    int n;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&x[i]);
    for(int i=1;i<=n;i++)scanf("%lld",&y[i]);
    int now=1,ans=0;
    for(int i=1;i<=n;i++){
        while(x[i]&&x[i]>=y[now]){
            ans+=y[now]*abs(i-now);
            x[i]-=y[now];
            y[now]=0;
            now++;
        }
        ans+=x[i]*abs(i-now);
        y[now]-=x[i];
        x[i]=0;
    }
    printf("%lld\n",ans);
    return 0;
}

T3

忘了,你说得对但是我不会生成函数。

T4

忘了,反正 \(O(n\log n)\) 链表自己写小常数 \(\gcd\) 可以直接飞过 47pts,我不会min25筛。

posted @ 2025-08-24 11:19  Igunareo  阅读(13)  评论(0)    收藏  举报