ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2020ICPC·小米 网络选拔赛第一场

2020-10-26 21:32:24  阅读:300  来源: 互联网

标签:cur &# int rep cin 183 2020ICPC ll cout


A

枚举倍数就行了

然后挨个去查找, 调和级数nlogn,

这就是好多人这样过的, 这是数据水了....

毕竟 n 是 1e7, 这是卡爆他们的数据

100000
1, 2, ..., 9999, 10000000 

大概需要计算1e8+(还不算循环里的两条指令), 再好的评侧鸡也不能跑到 1e8+ 吧..

所以我们应注意到, 在累加 i 的时候会重复, 枚举素数倍就好了, 复杂度就成了 nloglogn, 2e7+

const int N = 1e7 + 5;
 
int n, m, _, k;
ll a[N], b[N], d[N];
int prime[N], tot;
bool v[N];

void init(int n) {
    rep (i, 2, n) {
        if (!v[i]) prime[++tot] = i;
        for (int j = 1; prime[j] <= n / i && j <= tot; ++j) {
            v[prime[j] * i] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

int main() {
    IOS; cin >> n; init(1e7);
    rep (i, 1, n) cin >> a[i], ++b[a[i]];
    ll ans = 0;
    per (i, 1e7, 1) {
        for (int j = 1; prime[j] <= 1e7 / i; ++j) umax(d[i], d[prime[j] * i]);
        umax(ans, d[i] += b[i]);
    }
    cout << ans;
    return 0;
}

B

对每个点能到的点(即 x 到 y 的直线路径上没 墙 )建边, 跑最短路

怎么判线段相交就不贴了, 板子太长, 用你自己的几何板子就行了

int n, m, k, _;
int h[N], ne[M << 1], to[M << 1], tot;
double co[M << 1], dis[N];
bool v[N];

void add(int u, int v, double c) {
    ne[++tot] = h[u]; to[h[u] = tot] = v; co[tot] = c;
    ne[++tot] = h[v]; to[h[v] = tot] = u; co[tot] = c; 
}

int main() {
    IOS; cin >> n >> m >> k;
    rep (i, 0, k) pos[i << 1].in(), pos[i << 1 | 1].in();
    rep (i, 0, (k << 1) + 1) {
        dis[i] = 2e9;
        rep (j, i + 1, (k << 1) + 1) {
            bool f = 1;
            rep (_, 0, k - 1) 
                if (pan_cross_LL(pos[i], pos[j], pos[_ << 1], pos[_ << 1 | 1])) f = 0;
            if (f) add(i, j, Len(pos[i] - pos[j]));
        }
    }
    priority_queue<pair<double, int>> q; q.push({ 0, k << 1}); dis[k << 1] = 0;
    while (!q.empty()) {
        int x = q.top().se; q.pop();
        if (v[x]) continue; v[x] = 1;
        for (int i = h[x]; i; i = ne[i]) {
            int y = to[i]; double w = dis[x] + co[i];
            if (w >= dis[y]) continue;
            dis[y] = w; q.push({ -w, y });
        }
    }
    cout << setiosflags(ios::fixed) << setprecision(4) << dis[k << 1 | 1];
    return 0;
}

C

题意模拟,签到题

int main() {
    IOS; string s;
    cin >> s; ll cnt = 0;
    rep (i, 0, s.size() - 1) {
        if (s[i] == 'w') ++cnt;
        if (!i || s[i] == 'v') continue;
        if (s[i] != 'w') continue;
        if (s[i - 1] == 'w') ++cnt;
    }
    cout << cnt;
    return 0;
}

D

tarjan板子题, 板子就不贴, 其他专栏贴过

int main() {
    IOS; cin >> n >> m;
    tot = 1; totc = df = 0;
    rep(i, 1, n) h[i] = dfn[i] = cut[i] = 0;
    rep(i, 1, m) {
        int u, v; cin >> u >> v;
        add(u, v); add(v, u);
    }

    int sum = 0;
    rep(i, 1, n) if (!dfn[i]) root = i, tarjan(i), ++sum;

    rep(i, 1, n) cout << sum + cut[i] << ' ';
    return 0;
}

F

二分就行, 记得 m * L 的地方可能爆ll, 用__int128

ll r[N], l[N], L, R, a[N];
 
bool check(__int128 m) {
    ll cur = 0, res = 0;
    rep(i, 1, n) {
        ll c = a[i] / m;
        if (c < l[i]) return 0;
        umin(c, r[i]); cur += c * m;
        if (c == r[i]) continue;
        res += a[i] % m;
    }
    if (cur + res >= m * L) return 1;
    return 0;
}
 
int main() {
    IOS; cin >> n >> L >> R;
    ll mx = 0, mi = 0, s = 0;
    rep(i, 1, n) cin >> a[i], s += a[i];
    rep(i, 1, n)
        cin >> l[i] >> r[i], mi += l[i], mx += r[i];
    if (mi > R || mx < L) { cout << 0; return 0; }
    ll l = 0, r = s;
    while (l < r) {
        ll mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    cout << l;
    return 0;
}

I

搜索low爆了

你在每个点走的方向唯一的, 那直接将 这个点和将要走到的点合并不好吗?

对环打标记

最后父亲等于自己的 且没有标记的, 是能走出去的点, 答案就是这些点和这些点的孩子的个数

int get(int x, int y) {
    return (x - 1) * m + y;
}
 
int main() {
    IOS; cin >> n >> m;
    rep(i, 1, n) rep(j, 1, m) k = get(i, j), f[k] = k, siz[k] = 1;
    rep(i, 1, n) {
        cin >> s[i] + 1;
        rep(j, 1, m)
            if (s[i][j] == 'S') { if (i + 1 <= n) unit(get(i + 1, j), get(i, j)); }
            else if (s[i][j] == 'W') { if (i - 1 > 0) unit(get(i - 1, j), get(i, j)); }
            else if (s[i][j] == 'A') { if (j - 1 > 0) unit(get(i, j - 1), get(i, j)); }
            else { if (j + 1 <= m) unit(get(i, j + 1), get(i, j)); }
    }
    int ans = 0;
    rep(i, 1, n) rep(j, 1, m) {
        int id = get(i, j);
        if (f[id] != id || v[id]) continue;
        ans += siz[id];
    }
    cout << ans;
    return 0;
}

J

和开关问题一样, 还比他简单, 直接从 (1, 1) 开始改, 当无法改的的时候 不为0 就 QAQ

主要是裸一个二维区间查询和修改的数据结构, 线段树和树状数组都行, 我用的树状(代码短)


int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n >> m >> x >> y;
        rep(i, 1, n) rep(j, 1, m) {
            cin >> a[i][j];
            c[0][i][j] = c[1][i][j] = c[2][i][j] = c[3][i][j] = 0; //树状数组的初始化
        }
        bool f = 1;
        rep(i, 1, n - x + 1) {
            if (!f) break;
            rep(j, 1, m - y + 1) {
                int cur = a[i][j] + ask(i, j, i, j);
                if (cur < 0) { f = 0; break; }
                if (cur == 0) continue;
                add(i, j, i + x - 1, j + y - 1, -cur);
            }
            rep(j, m - y + 2, m) {
                int cur = a[i][j] + ask(i, j, i, j);
                if (cur != 0) { f = 0; break; }
            }
        }
        rep(i, n - x + 2, n) {
            if (!f) break;
            rep(j, 1, m) {
                int cur = a[i][j] + ask(i, j, i, j);
                if (cur != 0) { f = 0; break; }
            }
        }
        if (f) cout << "^_^\n";
        else cout << "QAQ\n";
    }
    return 0;
}

标签:cur,&#,int,rep,cin,183,2020ICPC,ll,cout
来源: https://www.cnblogs.com/2aptx4869/p/13879662.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有