平时七测
题解:
第一题
注意初值(选第一天特殊处理); 然后考试的时候读入写错了,耍了两天退化成了SB;
#include<bits/stdc++.h> using namespace std; #define ll long long const int M = 2005; ll dp[M][2005], sum[2][M]; const ll mod = 998244353; inline ll moc(ll a){return a >= mod ? a - mod : a;} ll ksm(ll a, ll b){ ll ret = 1; for(;b;b >>= 1,a=a*a%mod) if(b&1)ret=ret*a%mod; return ret; } ll C(ll a, ll b){ if(b > a) return 0; if(!a || a == b) return 1; ll c = a - b; if(c < b) swap(c, b); ll fz = 1, fm = 1; for(ll i = c + 1; i <= a; i++) fz = fz * i % mod; for(ll i = 1; i <= b; i++) fm = fm * i % mod; fm = ksm(fm, mod - 2); return fz * fm % mod; } ll Lucas(ll a, ll b){ return C(a / mod, b / mod) * C(a % mod, b % mod) % mod; } int main(){ freopen("contract.in","r",stdin); freopen("contract.out","w",stdout); int m, n; ll d; //cout<<ksm(2ll, mod-2)<<endl; while(scanf("%d%lld%d", &n, &d, &m) == 3){ if(!n&&!m&&!d)break; memset(dp, 0, sizeof(dp)); memset(sum, 0, sizeof(sum)); for(int i=1;i<=n && i < m;++i){ dp[1][i] = 1; } for(int i=1;i<=n;++i){ sum[0][i] = sum[0][i-1] + dp[1][i]; if(i > m - 1) dp[1][i] = 0; } int u = 0; for(int i = 2; i <= n && i <= d; i++){ u ^= 1; memset(sum[u], 0, sizeof(sum[u])); int ret = min(n, i*(m-1)); for(int j = i; j <= n; j++){ if(j <= m )dp[i][j] = sum[u^1][j-1]; else dp[i][j] = (mod + (sum[u^1][j-1] - sum[u^1][j-m]) % mod) % mod; sum[u][j] = moc(sum[u][j-1] + dp[i][j]); // printf("%d %d %lld %lld\n",i,j, dp[i][j], sum[u^1][j-1] - sum[u^1][j-m]); } } ll ans = 0; for(int i = 1; i <= min((ll)n, d); i++){ ll tmp = Lucas(d, i); ans = moc(ans + dp[i][n] * tmp % mod); // printf("%d %lld %lld\n", i, dp[i][n], tmp); } printf("%d\n", ans); } }
第二题:思路新奇的一道题;
#include<bits/stdc++.h> using namespace std; const int M = 1e5 + 50, ME = 5 * M; struct edge{int v, nxt, w;}G[ME]; int h[M], tot, ans = 2e9; bool inq[M]; void add(int u, int v, int w){ G[++tot].v = v, G[tot].w = w, G[tot].nxt = h[u], h[u] = tot; } int dd[M], q[M], p[M]; queue<int> Q; void init(){ memset(h, 0, sizeof(h)); tot = 0; ans = 2e9; } int main(){ freopen("leave.in","r",stdin); freopen("leave.out","w",stdout); int T; scanf("%d", &T); while(T--){ init(); int n, m, u, v, w, tp = 0; scanf("%d%d", &n, &m); for(int i = 1; i <= m; i++){ scanf("%d%d%d", &u, &v, &w); if(u==1)q[++tp]=v, p[tp]=w; if(v==1)q[++tp]=u, p[tp]=w; add(u, v, w); add(v, u, w); } for(int bit = 1; bit <= 15; bit++){ memset(dd, 127, sizeof(dd)); memset(inq, 0, sizeof(inq)); for(int i = 1; i <= tp; i++){ if(q[i] & (1<<(bit-1))){ Q.push(q[i]), dd[q[i]] = p[i], inq[q[i]] = 1; } } while(!Q.empty()){ int u=Q.front();Q.pop();inq[u]=0; for(int i=h[u];i;i=G[i].nxt){ int v=G[i].v; //if(v > 1e4)fprintf(stderr,"%d %d\n", u, v); if(v != 1 && dd[v] > dd[u] + G[i].w) { dd[v] = dd[u] + G[i].w; if(!inq[v])inq[v] = 1, Q.push(v); } } } for(int i = 1; i <= tp; i++){ if(q[i] & (1<<(bit-1))); else { // printf("at i = %d,dis = %d,val = %d\n",i,dd[q[i]],p[i]); ans = min(ans, dd[q[i]] + p[i]); } } } if(ans == 2e9)puts("-1"); else printf("%d\n", ans); } }
第三题:一道讲过的题,但是代码超级难写
#include<bits/stdc++.h> using namespace std; #define ex(i, u) for(int i = h[u]; i; i = G[i].nxt) const int M = 2e5 + 10, mod = 998244353; int tot, h[M], fa[M], n, c[M], deg[M], t1, t2, t3; int cnt, vcnt, now, seg, ok, siz[M], b[M]; long long ans1; long long ans2; struct edge{int v, nxt, w, vis;}G[M<<1]; void add(int u, int v){ G[++tot].v = v, G[tot].w = 0, G[tot].nxt = h[u], G[tot].vis = 0, h[u] = tot; G[++tot].v = u, G[tot].w = 1, G[tot].nxt = h[v], G[tot].vis = 0, h[v] = tot; } bool vis[M], in[M]; void init(){ memset(h, 0, sizeof(h)); memset(deg, 0, sizeof(deg)); memset(in, 0, sizeof(in)); memset(siz, 0, sizeof(siz)); memset(vis, 0, sizeof(vis)); tot = 1; ans1 = 0; ans2 = 1; for(int i=1;i<=n<<1;i++)fa[i]=i; } int find(int x){ if(fa[x] == x) return x; return fa[x] = find(fa[x]); } void dfs1(int u, int f){ ex(i, u){ int v=G[i].v; if(v==f||in[v])continue; dfs1(v, u); now += (1-G[i].w); } } void dfs2(int u, int f){ if(now < cnt) cnt = now, seg = 1; else if(now == cnt) seg++; ex(i, u){ int v=G[i].v; if(v==f)continue; if(G[i].w > 0) now++; else now--; dfs2(v, u); if(G[i].w > 0) now--; else now++; } } int circle(int u){ vis[u]=1; ex(i, u){ if(G[i].vis)continue; G[i].vis = G[i^1].vis = 1; int v=G[i].v; if(vis[v]){ok = v;c[++vcnt] = u; in[u] = 1; break;} else circle(v); if(ok) { c[++vcnt] = u, in[u] = 1; break; } } if(ok == u) ok = 0; } int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*=f; } int main(){ freopen("back.in","r",stdin); freopen("back.out","w",stdout); int T=0, inf = 2e9; scanf("%d", &T); while(T--){ int u, v; scanf("%d", &n); init(); for(int i=1; i <=n; i++){ u = read(), v = read(); add(u, v); deg[u]++, deg[v]++; int fx = find(u), fy = find(v); if(fx == fy)continue; fa[fx] = fy; } for(int i=1;i<=n<<1;i++) if(find(i)!=i) siz[fa[i]]++, deg[fa[i]] += deg[i]; for(int i=1;i<=n<<1;i++) if(find(i) == i){ siz[i]++; if(!deg[i])continue; cnt = inf; now = 0; seg = 0; int gx1, gx2; if(deg[i]/2 == siz[i]-1){ dfs1(i, 0); cnt = now; dfs2(i, 0); gx1 = cnt; gx2 = seg; } else if(deg[i]/2 == siz[i]){ ok = vcnt = 0; t3 = 0, t1 = 0, t2 = 0; circle(i); c[0] = c[vcnt], c[vcnt + 1] = c[1]; for(int p=1;p<=vcnt;p++){ int u=c[p]; ex(i, u) if(G[i].v == c[p+1] && G[i].w){ t1++; break; } } t2 = vcnt - t1; cnt = min(t1, t2); for(int p=1;p<=vcnt;p++){ int u=c[p]; ex(i, u) if(G[i].v != c[p+1] && G[i].v != c[p-1]){ now = 0; dfs1(G[i].v, u); now += (1-G[i].w); t3 += now; } } gx1 = cnt + t3; gx2 = 1 + (t1 == t2); } if(cnt == inf){ ans1 = ans2 = -1; break; } ans1 += gx1; //printf("%lld %d\n", ans1, gx1); ans2 = ans2 * gx2 % mod; } printf("%lld %lld\n", ans1, ans2); } }