2020杭电多校第六场

1001.Road To The 3rd Building

遍历1-n,计算所有长度为 i 的区间的值的和。

维护两个前缀和就可以计算。分母也显而易见。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

ll mod = 1e9 + 7;
ll inv[200010];
ll ksm(ll a, ll b)
{
    a %= mod;
    ll res = 1;
    for (; b; b >>= 1, a = a * a % mod)
        if (b & 1)
            res = res * a % mod;
    return res;
}
ll sum[200010], sum1[200010];
ll n, ans, f;
ll tmp1, tmp2;
inline void solve(int T)
{
    cin >> n;
    ans = sum[0] = sum[0] = 0;
    rep(i, 1, n)
    {
        cin >> f;
        sum[i] = (sum[i - 1] + f) % mod;
        sum1[i] = (sum1[i - 1] + f * min((ll)i, n - i + 1)) % mod;
    }
    rep(i, 1, n)
    {
        tmp1 = i;
        tmp2 = n - i + 1;
        if (tmp1 > tmp2)
            swap(tmp1, tmp2);
        ans = (ans + ((sum[tmp2] - sum[tmp1 - 1] + mod) % mod * tmp1 % mod + sum1[n] - sum1[tmp2] + sum1[tmp1 - 1] + mod) % mod * inv[i] % mod) % mod;
    }
    cout << ans * ksm(n * (n + 1) / 2, mod - 2) % mod << endl;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    inv[1] = 1;
    rep(i, 2, 200010) inv[i] = (mod - mod / i) * inv[mod % i] % mod;

    int T = 1;
    cin >> T;
    rep(i, 1, T) solve(i);
}
View Code

 

1002.Little Rabbit's Equation

模拟

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

char s[20];
ll n[20];
ll a, b, c;
ll x, y, z;
int jz, flag;
inline void solve(int T)
{
    memset(s, 0, sizeof(s));
    while (cin >> s)
    {
        jz = 2;
        for (int i = 0;; i++)
        {
            if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/')
                a = i - 1;
            else if (s[i] == '=')
                b = i - 1;
            else if (s[i] == 0)
            {
                c = i - 1;
                break;
            }
            else
            {
                n[i] = s[i] >= '0' && s[i] <= '9' ? s[i] - '0' : s[i] - 'A' + 10;
                jz = max((ll)jz, n[i] + 1);
            }
        }
        rep(k, jz, 16)
        {
            x = y = z = flag = 0;
            rep(i, 0, a) x = x * k + n[i];
            rep(i, a + 2, b) y = y * k + n[i];
            rep(i, b + 2, c) z = z * k + n[i];
            if (s[a + 1] == '+' && x + y == z)
                flag = k;
            if (s[a + 1] == '-' && x - y == z)
                flag = k;
            if (s[a + 1] == '*' && x * y == z)
                flag = k;
            if (s[a + 1] == '/' && x == z * y)
                flag = k;
            if (flag)
                break;
        }
        if (flag)
            cout << flag << endl;
        else
            cout << "-1\n";
        memset(s, 0, sizeof(s));
    }
}
int main()
{
    // ios_base::sync_with_stdio(0);
    // cin.tie(0);
    // cout.tie(0);

    int T = 1;
    // cin >> T;
    rep(i, 1, T) solve(i);
}
View Code

 

1006.A Very Easy Graph Problem

题目的意思是求所有为1的点到所有为0的点的最小距离和。

边长的特性,保证了可以按顺序加边做最小生成树,这样任意两点的距离一定最短。

然后在树上跑一边dfs即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

int mod = 1e9 + 7;
int pre[100010];
int find(int x) { return x == pre[x] ? x : pre[x] = find(pre[x]); }

#define pii pair<int, int>
struct point
{
    int num0, num1, sum0, sum1;
} p[100010];
int pow2[200010];

int n, m;
int a[100010];
vector<pii> son[100010];
int u, v;
int ans;

void dfs(int now, int fa)
{
    for (vector<pii>::iterator it = son[now].begin(); it != son[now].end(); it++)
    {
        pii q = *it;
        if (q.first == fa)
            continue;
        dfs(q.first, now);
        ans = (ans + 1ll * p[q.first].sum1 * p[now].num0 % mod + 1ll * p[q.first].num1 * p[now].sum0 % mod) % mod;
        ans = (ans + 1ll * p[q.first].sum0 * p[now].num1 % mod + 1ll * p[q.first].num0 * p[now].sum1 % mod) % mod;
        ans = (ans + (1ll * p[q.first].num0 * p[now].num1 % mod + 1ll * p[q.first].num1 * p[now].num0 % mod) * q.second % mod) % mod;
        p[now].num0 += p[q.first].num0;
        p[now].num1 += p[q.first].num1;
        p[now].sum0 = (p[now].sum0 + p[q.first].sum0 + 1ll * q.second * p[q.first].num0 % mod) % mod;
        p[now].sum1 = (p[now].sum1 + p[q.first].sum1 + 1ll * q.second * p[q.first].num1 % mod) % mod;
    }
}

inline void solve(int T)
{
    cin >> n >> m;
    rep(i, 1, n)
    {
        cin >> a[i];
        pre[i] = i;
        son[i].clear();
        p[i] = (point){a[i] == 0, a[i] == 1, 0, 0};
    }
    rep(i, 1, m)
    {
        cin >> u >> v;
        if (find(u) != find(v))
        {
            pre[find(u)] = find(v);
            son[u].push_back(make_pair(v, pow2[i]));
            son[v].push_back(make_pair(u, pow2[i]));
        }
    }
    ans = 0;
    dfs(1, 0);
    cout << ans << endl;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    pow2[0] = 1;
    rep(i, 1, 200000) pow2[i] = 2ll * pow2[i - 1] % mod;

    int T = 1;
    cin >> T;
    rep(i, 1, T) solve(i);
}
View Code

 

1009.Divisibility

签到

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

ll b, x;
inline void solve(int T)
{
    cin >> b >> x;
    puts((b - 1) % x ? "F" : "T");
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int T = 1;
    cin >> T;
    rep(i, 1, T) solve(i);
}
View Code

 

posted @ 2020-08-07 13:10  若讷  阅读(222)  评论(0编辑  收藏  举报