模拟赛直接升天 ios
100 + 100 + 100 + 30 秒变 50 + 30 + 0 + 30数组
自身的问题仍是有点多ide
有一张 n 个点, m条边的无向图,点从 1到 n标号。ui
时刻 0时,你在结点1 。你须要用最少的时间从结点 1走到结点n 。经过m条边中的每一条都要花必定的时间。spa
每一个结点会有可能在某些时刻被限制。一个结点 x 在时刻T被限制,意味着这个结点的人在时刻T不能从这个点x走出去。3d
你只能在整数时刻进出某个结点,一个结点能够逗留任意非负整数时间。code
如今,请问你最少须要多少时间能从结点 1走到结点n 。blog
能够看出确定越早到一个点越优 在这个点上等再到这个点的全部连点 和 到连点后再等待出点 是同一个道理,咱们记录每一个点的最先到达时间,游戏
用最先出点时间更新它的连点 跑一遍最短路就好了 同时 数组 须要 开大 且 开始定义的最大值要很大 否则直接wa了。it
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #define f(i, a, b) for (long long i = a; i <= b; i++) using namespace std; priority_queue<pair<long long, long long> > QAQ; long long n, m, k, begi, fina, v, head[100100], d[100100]; bool tim[5000][5000]; bool visit[100010]; struct QWQ { long long to, next, value; } edge[100100]; void make(long long a, long long b, long long c) { edge[++edge[0].value].to = b; edge[edge[0].value].value = c; edge[edge[0].value].next = head[a]; head[a] = edge[0].value; } void dij() { QAQ.push(make_pair(0, 1)); d[1] = 0; while (QAQ.size()) { long long num = QAQ.top().second; QAQ.pop(); if(visit[num]) continue; visit[num] = 1; long long p = d[num]; while(tim[num][p])p++; for (long long i = head[num]; i; i = edge[i].next) { if (p + edge[i].value < d[edge[i].to]) { d[edge[i].to] = p + edge[i].value; QAQ.push(make_pair(-d[edge[i].to], edge[i].to)); } } } } int main() { freopen("travel.in", "r", stdin); freopen("travel.out", "w", stdout); scanf("%lld%lld", &n, &m); f(i, 1, m) { scanf("%lld%lld%lld", &begi, &fina, &v); make(begi, fina, v); make(fina, begi, v); } f(i, 1, n) { scanf("%lld", &k); long long t; f(j, 1, k) { scanf("%lld", &t); tim[i][t] = 1; } d[i] = 1e16; } dij(); printf("%lld", d[n]); return 0; }
#include<cstdio> #include<algorithm> using namespace std; const long long mo=998244353; const int MAXN=100000+5; long long a[MAXN],inv[MAXN],fact[MAXN]; long long power(long long a,long long b) { long long t=1,y=a%mo; while (b) { if (b&1) t=t*y%mo; y=y*y%mo; b>>=1; } return t; } int main() { freopen("card.in","r",stdin); freopen("card.out","w",stdout); int n,k; scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&a[i]); fact[0]=inv[0]=1; for (int i=1;i<=n;i++) { fact[i]=fact[i-1]*i%mo; inv[i]=power(fact[i],mo-2); } int sum; long long ans=0; for (int i=0;i<=30;i++) { sum=0; for (int j=1;j<=n;j++) sum+=((a[j]>>i)&1); for (int j=1;j<=min(k,sum);j++) if (k-j<=n-sum&&j&1) ans=(ans+fact[sum]*inv[j]%mo*inv[sum-j]%mo*fact[n-sum]%mo*inv[k-j]%mo*inv[n-sum-k+j]%mo*(1ll<<i)%mo)%mo; } printf("%lld",ans); return 0; }
C D 待续