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筛。

浙公网安备 33010602011771号