平时七测

题解:

第一题

注意初值(选第一天特殊处理); 然后考试的时候读入写错了,耍了两天退化成了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
",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
", i, dp[i][n], tmp);
        }
            
        printf("%d
", ans);
    }
} 
View Code

第二题:思路新奇的一道题;

#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
", 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
",i,dd[q[i]],p[i]);
                    ans = min(ans, dd[q[i]] + p[i]);
                }
            }    
        }
        if(ans == 2e9)puts("-1");
        else printf("%d
", ans);
    }
} 
View Code

 第三题:一道讲过的题,但是代码超级难写

#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
", ans1, gx1);
                ans2 = ans2 * gx2 % mod;
            }    
        printf("%lld %lld
", ans1, ans2);
    }
}
View Code
原文地址:https://www.cnblogs.com/EdSheeran/p/9740394.html