zoukankan      html  css  js  c++  java
  • 《多校补题》

    前言:高处不胜寒,但贵在坚守。

    Divisibility

    题解上都是从结论出发去证明的。但我觉得一开始不可能都知道结论。所以稍微从思考角度出发

    可以发现$y = c1* b^{n-1} + c2 * b^{n-2} + ... + cn * b^{0}$

    那么对于无限的f(y)操作,可以发现每次都是将所有位数加后重构继续加后重构。

    那么可以看成对x各位相加后的取模操作。

    那么题目就可以转化成:

    是否同时满足:

    $(c1* b^{n-1} + c2 * b^{n-2} + ... + cn * b^{0}) \equiv 0 mod (x)$时,

    也满足 $(c1 + c2 + ... + cn ) \equiv 0 mod (x)$.

    可以发现的是b = 1时,满足两式相等,那么肯定性质相同。

    即可以发现b mod x == 1时,可以使两式相等,永远满足。

    当b mod x != 1时。

    证明:

    如果b < x,那么显然不行,可以构造一个x的倍数,然后x的倍数最终会被转化到 < x。此时无法满足性质相同。

    如果b >= x.令 $y = 0+0+....1*b^{1}+x-1$.

    若$b+x-1 \equiv 0 (mod x)$

    即$b \equiv 1 (mod x)$

    因为b mod x != 1,所以矛盾,无法满足。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline LL read()
    {
        LL 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<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    int main()
    {
        int ca;ca = read();
        while(ca--)
        {
            LL b,x;b = read(),x = read();
            if(b%x == 1) printf("T\n");
            else printf("F\n");
        }
        system("pause");
        return 0;
    }
    View Code

    Little Rabbit's Equation

    难度最低的一个题吧。(进制转换对我来说还是很难受)

    考虑这么多种进制会很难处理,那么将所有数都转化为10进制即可(注意这里最大15位数,所以开longlong)

    记一下进制转换:将其他进制转换为10进制,以该进制为基数来模拟10进制+来实现转化。

    注意的是,如果当前值>=进制,那么说明这个数不属于这个进制,那么次时查找肯定无效。

    PS:printf和cin混用导致debug了蛮久。。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const LL N = 2e14+5;
    const int M = 1005;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    unordered_map<char,LL> mp;
    void init()
    {
        mp['0'] = 0,mp['1'] = 1,mp['2'] = 2,mp['3'] = 3,mp['4'] = 4,mp['5'] = 5;
        mp['6'] = 6,mp['7'] = 7,mp['8'] = 8,mp['9'] = 9,mp['A'] = 10,mp['B'] = 11;
        mp['C'] = 12,mp['D'] = 13,mp['E'] = 14,mp['F'] = 15;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        init();
        string s;
        while(cin >> s)
        {
            int flag = 0;
            for(int ba = 2;ba <= 16;++ba)
            {
                LL a = 0,b = 0,c = 0,t = 0;
                int id,tag = 0;
                for(int i = 0;i < s.size();++i)
                {
                    if(s[i] == '+') a = t,t = 0,id = 1;
                    else if(s[i] == '-') a = t,t = 0,id = 2;
                    else if(s[i] == '*') a = t,t = 0,id = 3;
                    else if(s[i] == '/') a = t,t = 0,id = 4;
                    else if(s[i] == '=') b = t,t = 0;
                    else 
                    {
                        if(mp[s[i]] >= ba){tag = 1;break;}
                        t = t*ba+mp[s[i]];
                    }
                }
                if(tag) continue;
                c = t;
               // printf("a is %lld b is %lld c is %lld\n",a,b,c);
                if(id == 1 && a+b == c) flag = ba;
                if(id == 2 && a-b == c) flag = ba;
                if(id == 3 && a*b == c) flag = ba;
                if(id == 4 && b*c == a) flag = ba;
                if(flag) break;
            }
            if(flag) cout << flag << endl;
            else cout << "-1" << endl;
        }
        system("pause");
        return 0;
    }
    View Code

    Road To The 3rd Building

    可以发现的是,对于长度一样的组合,他们的长度是一样的。

    那么记录下前缀和即可。

    这里由于取模后sum[n-i+1]可能会<sum[i-1],所以要加模数防负数。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline LL read()
    {
        LL 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<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    LL quick_mi(LL a,LL b)
    {
        LL re = 1;
        a %= Mod;
        while(b)
        {
            if(b&1) re = (re*a)%Mod;
            a = (a*a)%Mod;
            b >>= 1;
        }
        return re;
    }
    LL sum[N],a[N];
    int main()
    {
        int ca;ca = read();
        while(ca--)
        {
            LL n;n = read();
            memset(sum,0,sizeof(sum));
            for(int i = 1;i <= n;++i) a[i] = read(),sum[i] = (sum[i-1]+a[i])%Mod;
            LL ans = 0,pre = 0;
            for(int i = 1;i <= n/2;++i)
            {
                pre = (pre+(sum[n-i+1]-sum[i-1])%Mod+Mod)%Mod;
                ans = (ans+pre*quick_mi(i,Mod-2)%Mod)%Mod;
                ans = (ans+pre*quick_mi(n-i+1,Mod-2)%Mod)%Mod;
            }
            if(n%2 == 1)
            {
                pre = (pre+a[n/2+1])%Mod;
                ans = (ans+pre*quick_mi(n/2+1,Mod-2)%Mod)%Mod;
            }
            LL ma = n*(n+1)/2;
            ans = ans*quick_mi(ma,Mod-2)%Mod;
            printf("%lld\n",ans);
        }
        system("pause");
        return 0;
    }
    View Code

    A Very Easy Graph Problem

    递推了一个小时终于递推出了(i,j)可轮换的换根dp的转移式。

    结果一看题不可轮换,人傻了。。(先记录一下,毕竟是努力的结果)

    可轮换代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    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<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    struct Node{int to;LL dis;};
    vector<Node> G[N];
    int n,m,a[N],fa[N];
    LL dp[N][2],num[N][2],cnt1 = 0,cnt0 = 0;//num[2][0]-向下有多少0点,num[2][1]-1点,dp[2][0]向下的0的距离总和,dp[2][1]向下的1距离总和
    int Find(int x)
    {
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    LL quick_mi(LL a,LL b)
    {
        LL re = 1;
        a %= Mod;
        while(b)
        {
            if(b&1) re = (re*a)%Mod;
            a = (a*a)%Mod;
            b >>= 1;
        }
        return re;
    }
    LL inv(LL n){return quick_mi(n,Mod-2)%Mod;}
    void dfs(int u,int fa)
    {
        if(a[u] == 1) num[u][1] = 1;
        else num[u][0] = 1;
        for(auto v : G[u])
        {
            if(v.to == fa) continue;
            dfs(v.to,u);
            num[u][0] += num[v.to][0];
            num[u][0] %= Mod;
            num[u][1] += num[v.to][1];
            num[u][1] %= Mod;
            dp[u][0] = (dp[u][0]+dp[v.to][0]+(num[v.to][0]*v.dis)%Mod)%Mod;
            dp[u][1] = (dp[u][1]+dp[v.to][1]+(num[v.to][1]*v.dis)%Mod)%Mod;
        }
    }
    void dfs1(int u,int fa,LL dis)
    {
        if(fa != 0)
        {
            dp[u][1] = (dp[u][1]+((dp[fa][1]-dp[u][1]-num[u][1]*dis%Mod)+Mod)%Mod+((cnt1-num[u][1])+Mod)%Mod*dis%Mod)%Mod;
            dp[u][1] = (dp[u][1]+Mod)%Mod;
            dp[u][0] = (dp[u][0]+((dp[fa][0]-dp[u][0]-num[u][0]*dis%Mod)+Mod)%Mod+((cnt0-num[u][0])+Mod)%Mod*dis%Mod)%Mod;
            dp[u][0] = (dp[u][0]+Mod)%Mod;
        }
        for(auto v : G[u])
        {
            if(v.to == fa) continue;
            dfs1(v.to,u,v.dis);
        }
    }
    int main()
    {
        int t;t = read();
        while(t--)
        {
            n = read(),m = read();
            memset(dp,0,sizeof(dp));
            memset(num,0,sizeof(num));
            cnt1 = cnt0 = 0;
            for(int i = 1;i <= n;++i) 
            {
                a[i] = read(),G[i].clear(),fa[i] = i;
                if(a[i] == 1) cnt1++;
                else cnt0++;
            }
            for(int i = 1;i <= m;++i)
            {
                int u,v;u = read(),v = read();
                int xx = Find(u),yy = Find(v);
                if(xx != yy)
                {
                    fa[xx] = yy;
                    G[u].push_back(Node{v,quick_mi(2,i)});
                    G[v].push_back(Node{u,quick_mi(2,i)});
                }
            }
            dfs(1,0);
            dfs1(1,0,0);
            LL ans = 0;
            for(int i = 1;i <= n;++i) printf("i is %d 0 is %lld 1 is %lld\n",i,dp[i][0],dp[i][1]);
            for(int i = 1;i <= n;++i) ans = (ans+dp[i][a[i]^1])%Mod;
            printf("%lld\n",ans);
        }
        system("pause");
        return 0;
    }
    View Code

     正解:

    可以发现,这个图并不是一个树。

    但是,我们要的距离是最短距离,那么可以在输入的时候去维护一棵最小的生成树。

    因为满足$2^{i} > 2^{i-1} + 2^{i-2} + ... 2^{1}$

    那么我们选择越前面的边,显然代价越小。

    那么就可以维护输入顺序的最小生成树即可。

    如何统计答案,因为是不可轮换式的。

    那么我们可以去统计每条边对答案的贡献。

    所以我们dfs处理出每个点下面的0,1的数量(包括该点)。

    然后对于一条边的贡献就是他一边的1的数量*另一边的0的数量*该边的权值 (即num1 * num0 * cost)  .还有 0 * 1 * cost

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    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<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    struct Node{int to;LL dis;};
    vector<Node> G[N];
    int n,m,a[N],fa[N];
    LL num[N][2],ans,cnt1,cnt0;
    int Find(int x)
    {
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    LL quick_mi(LL a,LL b)
    {
        LL re = 1;
        while(b)
        {
            if(b&1) re = (re*a)%Mod;
            a = (a*a)%Mod;
            b >>= 1;
        }
        return re;
    }
    void dfs(int u,int fa)
    {
        num[u][a[u]] = 1;
        for(auto v : G[u])
        {
            if(v.to == fa) continue;
            dfs(v.to,u);
            num[u][0] += num[v.to][0];
            num[u][0] %= Mod;
            num[u][1] += num[v.to][1];
            num[u][1] %= Mod;
        }
    }
    void dfs1(int u,int fa,LL dis)
    {
        if(fa != 0)
        {
            ans = (ans+dis*((num[u][0])*(cnt1-num[u][1])%Mod)%Mod)%Mod;
            ans = (ans+dis*((num[u][1])*(cnt0-num[u][0])%Mod)%Mod)%Mod;
        }
        for(auto v : G[u])
        {
            if(v.to == fa) continue;
            dfs1(v.to,u,v.dis);
        }
    }
    int main()
    {
        int t;t = read();
        while(t--)
        {
            n = read(),m = read();
            memset(num,0,sizeof(num));
            ans = cnt1 = cnt0 = 0;
            for(int i = 1;i <= n;++i) 
            {
                a[i] = read(),G[i].clear(),fa[i] = i;
                if(a[i] == 1) cnt1++;
                else cnt0++;
            }
            for(int i = 1;i <= m;++i)
            {
                int u,v;u = read(),v = read();
                int xx = Find(u),yy = Find(v);
                if(xx != yy)
                {
                    fa[xx] = yy;
                    G[u].push_back(Node{v,quick_mi(2,i)});
                    G[v].push_back(Node{u,quick_mi(2,i)});
                }
            }
            dfs(1,0);
            dfs1(1,0,0);
            printf("%lld\n",ans);
        }
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    威马汽车Java实习面试(offer到手含面试经验及答案)
    满帮集团Java实习面试(offer到手含面试经验及答案)
    云杉世界Java实习面试(offer到手含面试经验及答案)
    商汤科技Java实习面试(offer到手含面试经验及答案)
    苏宁金融Java实习面试(offer到手含面试经验及答案)
    c++ 命令行执行
    2015 经典的ImageCaptioning论文
    c++ istringstream用法
    python操作excel——新建、写入、读取基本操作
    python包matplotlib绘制图像
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13452343.html
Copyright © 2011-2022 走看看