zoukankan      html  css  js  c++  java
  • 11.7模拟赛

    T1找循环节

    循环节的大小一定在49之内(7*7)

    读入int,挂成55

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    
    using namespace std;
    const int N = 1000000;
    
    #define LL long long
    
    LL f[N];
    LL n, A, B, js, bi1, bi2;
    
    inline LL read(){
        LL x = 0; char c = getchar();
        while(c < '0' || c > '9') c = getchar();
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x; 
    }int main()
    {
        freopen("attack.in", "r", stdin);
        freopen("attack.out", "w", stdout);
        A = read();
        B = read();
        n = read();
        bi1 = (A + B) % 7;
        bi2 = (A * bi1 + B) % 7;
        f[1] = f[2] = 1;
        f[3] = bi1;
        f[4] = bi2;
        for(int i = 5; ; i ++){
            f[i] = (A * f[i - 1] + B * f[i - 2]) % 7;
            if(f[i] == bi2 && f[i - 1] == bi1){
                js = i; break;
            }
        }
        for(int i = 1; i <= js - 3; i ++)
            f[i] = f[i + 2];
        js -= 4; 
        n -= 2;
        LL ans = n % js;
        if(!ans) printf("%lld", f[js] % 7);
        else printf("%lld", f[ans] % 7);
        return 0;
    }
    /*
    455322504
    473147848
    236471319
    */

    T2打表找规律

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int T;
    double n,m;
    inline 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("fseq.in","r",stdin);
        freopen("fseq.out","w",stdout);
        T=read();
        while(T--)
        {
            n=read();m=read();
            if(n<m)    {puts("0.000000");continue;}
            double _1=n-m+1,_2=n+1;
            printf("%.6lf
    ",_1/_2);
        }
        return 0;
    }

    T3

    /*
        套路题,没营养
        Tarjan缩点
        求出缩完点后树的直径
        对于每个点,若在最长链上就直接对两个端点取max
        否则就一直往上跳,累加边权,直到跳到最长链上
        然后做上一种情况的操作就好了
    */
    #include <cstdio>
    #include <iostream>
    #define rg register
    
    inline void read (int &n) {
        rg char c = getchar ();
        for (n = 0; !isdigit (c); c = getchar ());
        for (; isdigit (c); n = n * 10 + c - '0', c = getchar ());
    }
    
    #define Max 40008
    
    int _v[Max * 20], _n[Max * 20], list[Max * 20], EC = 1, _d[Max * 20];
    
    int N;
    inline void In (int u, int v, int d) {
        _v[++ EC] = v, _n[EC] = list[u], list[u] = EC, _d[EC] = d;
    }
    
    int t, sk[Max], DC, SC;
    int dfn[Max], low[Max], scc[Max];
    
    inline void cmin (int &a, int b) {
        if (b < a) a = b;
    }
    
    void Dfs (int n, int l) {
        sk[++ t] = n;
        dfn[n] = low[n] = ++ DC;
        for (rg int i = list[n], v; i; i = _n[i])
            if (i != l && i != (l ^ 1)) {
                if (!dfn[v = _v[i]]) Dfs (v, i), cmin (low[n], low[v]);
                else if (!scc[v]) cmin (low[n], dfn[v]);
            }
        if (low[n] == dfn[n]) {
            ++ SC;
            for (int r = n + 1; t && r != n; -- t)
                r = sk[t], scc[r] = SC;
        }
    }
    
    int ev[Max * 20], en[Max * 20], el[Max * 10], ec, ed[Max * 20];
    
    inline void _In (int u, int v, int d) {
        ev[++ ec] = v, en[ec] = el[u], el[u] = ec, ed[ec] = d;
        ev[++ ec] = u, en[ec] = el[v], el[v] = ec, ed[ec] = d;
    }
    
    bool Find (int x, int y) {
        for (rg int i = el[x]; i; i = en[i])
            if (ev[i] == y) return true;
        return false;
    }
    
    void Tarjan () {
        rg int i;
        for (i = 1; i <= N; ++ i) if (!dfn[i]) Dfs (i, 0);
        for (int n = 1; n <= N; ++ n)
            for (i = list[n]; i; i = _n[i])
                if (scc[n] != scc[_v[i]])
                    if (!Find (scc[n], scc[_v[i]])) {
                        _In (scc[n], scc[_v[i]], _d[i]);
                    }
    }
    int Answer[Max];
    int dis1[Max], dis2[Max], pos1, pos2, Max1, Max2, pre[Max];
    void Gc1 (int n, int F) {
        for (rg int i = el[n], v; i; i = en[i])
            if ((v = ev[i]) != F)
                dis1[v] = dis1[n] + ed[i], Gc1 (v, n);
        if (dis1[n] > Max1) Max1 = dis1[n], pos1 = n;
    }
    int f[Max];
    void Gc2 (int n, int F) {
        f[n] = F;
        for (rg int i = el[n], v; i; i = en[i])
            if ((v = ev[i]) != F) dis2[v] = dis2[n] + ed[i], Gc2 (v, n), pre[v] = n;
        if (dis2[n] > Max2) Max2 = dis2[n], pos2 = n;
    }
    bool isc[Max];
    inline int max (int a, int b) {
        return a > b ? a : b;
    }
    void GetAnswer () {
        Gc1 (1, 0), Gc2 (pos1, 0);
        rg int i;
        for (i = pos2; i; i = pre[i])
            isc[i] = true;
        rg int n;
        int res = 0, j;
        for (i = 1; i <= SC; ++ i) {
            res = 0;
            for (n = i; !isc[n] && n; n = f[n]) {
                for (j = el[n]; j; j = en[j])
                    if (ev[j] == f[n]) {
                        res += ed[j];
                        break;
                    }
            }
            res += max (dis2[n], Max2 - dis2[n]);
            Answer[i] = res;
        }
        for (i = 1; i <= N; ++ i)
            printf ("%d
    ", Answer[scc[i]]);
    }
    int main (int argc, char *argv[]) {
        int x, y, M, z;
        read (N), read (M);
        for (rg int i = 1; i <= M; ++ i)
            read (x), read (y), read (z), In (x, y, z), In (y, x, z);
    
        Tarjan ();
    
        GetAnswer ();
    
        return 0;
    }

    更好理解的思路:

    首先缩点

    然后找出树的直径

    对于在树上的点,输出该点到直径两端点的较大值

    否则输出该点到直径的距离+该点所在链与直径的交点处到直径两个端点的较大值

  • 相关阅读:
    [JSOI2008]巨额奖金(最小生成树计数)
    [HAOI2008] 糖果传递
    [SCOI2009]生日快乐
    BZOJ2821 作诗
    [HAOI2008]圆上的整点
    POJ1741
    AC自动机
    [JSOI2008]星球大战starwar
    二分图有关证明(感性版)
    初识Pentaho(一)
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7801248.html
Copyright © 2011-2022 走看看