Codeforces gym 103990

C - Correct

签到

prob.:

ICPC赛制规则,九点开始的场,有个队只交了一发且直接AC,给出提交时间,问罚时

code:

#include <bits/stdc++.h>
using namespace std;

signed main() {
    int hh, mm;
    cin >> hh >> mm;
    cout << (hh - 9 ) * 60 + mm;
}

F - Finalists

签到

prob.:

一共6个地区,给出final队伍名额分配规则,给出相应的数据,问t被分到的名额

code:

#include <bits/stdc++.h>

using namespace std;

struct node {
    string name;
    double val;
};

vector<node> vec;

signed main() {
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    for(int i = 0; i < 6; ++ i) {
        string s;
        cin >> s;
        double a, b, c, d, e;
        cin >> a >> b >> c >> d >> e;
        double tmp = a * 0.56 + b * 0.24 + c * 0.14 + d * 0.06 + e * 0.3;
        vec.push_back({s, tmp});
    }
    sort(vec.begin(), vec.end(), [&](node a, node b){
        return a.val> b.val;
    });
    int ans = n /6;
    n=n%6;
    for(int i = 0; i < n; ++ i) {
        if(vec[i].name == "t") ans ++;
    }
    cout << ans << endl;
}

H - Heximal (没写

prob.:

给一个n位的十进制数,问转化成六进制之后的位数

n 5e5

ideas:

我看榜都过穿了,但怎么想都不好写,一看题解是python,打扰了

D - Distance and Tree

prob.:

定义树上两个点的距离是这两个点的路径的长度

一个正向的问题是,给出n个点的树,n个点在二维平面上,平面上没有树边交叉,规定一个根,计算出根到每个点的距离

现在有根到每个点的距离数组,和n个点的位置(在一个大圆上平均分布),要求构造树边使得边不交叉且满足距离数组

ideas:

根到根的距离为0,判断找出唯一的根

对距离排序,贪心地将每个点连到相邻的距离恰好小1的点上

code:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int d[N];

vector<int> g[N];
set<int> vec;

set<int> st;

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    int n;
    cin >> n;

    vector<pair<int, int> > res;

    int rt = -1;
    for (int i = 1; i <= n; ++i) {
        cin >> d[i];
        g[d[i]].push_back(i);
        vec.insert( d[i]);
        if (d[i] == 0) {
            if (rt == -1) rt = i;
            else {
                cout << -1;
                return 0;
            }
        }
    }

    st.insert(rt);
    int L = rt, R = rt;

    for (auto dist : vec) {
        if (dist == 0) continue;
        for(auto x : g[dist]) {
            bool flag = false;
            if (x > R || x < L) {
                if (d[L] == dist - 1) {
                    res.push_back({L, x});
                    flag = true;
                } else if (d[R] == dist - 1) {
                    res.push_back({R, x});
                    flag = true;
                }
                if (!flag) {
                    cout << -1;
                    return 0;
                }
            }
            else {
                auto it = st.lower_bound(x);
                it--;
                if (d[*it] == dist - 1) {
                    res.push_back({*it, x});
                    flag = true;
                }
                else {
                    it = st.upper_bound(x);
                    if (d[*it] == dist - 1) {
                        res.push_back({*it, x});
                        flag = true;
                    }
                }

                if (!flag) {
                    cout << -1;
                    return 0;
                }
            }

        }

        for(auto x: g[dist]) {
            L= min(L, x);
            R= max(R, x);
            st.insert(x);
        }

    }

    for(auto [u, v] : res) {
        cout << u << " "<< v << "\n";
    }
}

G - Geekflix

prob.:

有n个视频,编号1到n,呈循环,每个视频有两个属性a和b

刚开始在1号,有三种操作,1.移动到编号-1的位置,2.移动到编号+1的位置,3.播放当前视频

第k次播放i号视频可以获得的价值为 m a x ( 0 , a i − ( k − 1 ) × b i ) max(0, a_i - (k -1)\times b_i) max(0,ai(k1)×bi)

求m次操作能获得的最大价值

n 200 m 1000 a, b 5000

ideas:

破环成链,枚举左右到达的端点(需要判断1号点是不是在区间内

把移动的操作数计算上,然后贪心地看视频

O ( n 2 m l o g m ) O(n^2 m logm) O(n2mlogm)

复杂度有点悬的样子但跑不满

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 1e3 + 10;
const int inf = 0x3f3f3f3f;

int a[N], b[N];

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; ++i) cin >> a[i], a[i + n] = a[i];
    for (int i = 0; i < n; ++i) cin >> b[i], b[i + n] = b[i];

    auto in = [&](int l, int r) {
        if(l <= 0 && 0 <= r) return true;
        if(l <= n && n <= r) return true;
        return false;
    };

    auto dis = [&](int l, int r) {
        int res =0;
        if(l == 0) return (r - l + 1);
        res = min(n - l , r - n) + (r- l + 1);
        return res;
    };

    auto calc = [&](int pos, int k) {
        return max(0, a[pos] - (k - 1) * b[pos]);
    };

    int ans = 0;
    for(int l = 0; l < 2 * n; ++ l) {
        for(int r = l; r <2 * n; ++ r ) {
            if(!in(l, r) || (r - l + 1) > n) continue;
            int time = m  - dis(l, r)+ 1;
            priority_queue<pair<int, pair<int, int>>> que;
            for(int i = l; i <= r; ++ i) {
                que.push({calc(i, 1), {i, 1}});
            }
            int res = 0;
            for(int i = 0; i < time; ++ i) {
                res += que.top().first;
                int pos = que.top().second.first;
                int k=que.top().second.second;
                que.pop();
                que.push({calc(pos, k + 1), {pos, k + 1}});
            }
            ans = max(res, ans);
        }
    }

    cout << ans << endl;
}

B - Balanced Seesaw Array

prob:

n个数的序列,定义一种特殊的子序列[l, r]满足条件为, ∃ k ∈ [ l , r ] , s t . ∑ i ( i − k ) × a i = 0 \exist k \in[l, r], st. \sum_{i} (i - k)\times a_i = 0 k[l,r],st.i(ik)×ai=0

三种操作1. 区间赋值 2.区间加 3.询问区间是否为特殊的子序列

n 1e5 q 1e6 保证ll够用

ideas:

拆一下式子, ∑ i ( i − k ) × a i = 0 = ∑ i a i × i − k × ∑ i a i \sum_{i} (i - k)\times a_i = 0 = \sum_i a_i \times i - k \times \sum_i a_i i(ik)×ai=0=iai×ik×iai

维护区间 a i a_i ai的和和 a i × i a_i\times i ai×i的和就可以O(1)判断k是否在区间内

需要注意的是如果两个和都是0的时候k可以任意取值,这时候也满足条件

线段树维护 1.区间赋值 2.区间加 3.区间和 4.区间 a i × i a_i\times i ai×i 的和

线段树两个lazytag,区间赋值和区间加,其中区间赋值的优先级大于区间加

细节看代码吧(其中asum表示 a i a_i ai的和,iisum表示 a i × i a_i\times i ai×i 的和,其他命名应该都挺好懂(大概

代码能力太差,在MASHUPS WA了一整页,我真的栓Q

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll N = 1e6 + 10;
const ll inf = 0x3f3f3f3f3f3f3f3f;

ll a[N];

struct node {
    ll l, r;
    ll asum, iisum; // sum of ai, sum of i * ai
    ll changeTag, addTag; // the priority of changeTag > addTag
};

node tr[N << 2];

void pushup(ll u) {
    tr[u].asum = tr[u << 1].asum + tr[u << 1 | 1].asum;
    tr[u].iisum = tr[u << 1].iisum + tr[u << 1 | 1].iisum;
}

void pushdown(ll u) {
    auto &rt = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];

    if (rt.changeTag != inf) {
        left.asum = rt.changeTag * (left.r - left.l + 1);
        left.iisum = (left.l + left.r) * (left.r - left.l + 1) / 2 * rt.changeTag;
        left.changeTag = rt.changeTag, left.addTag = 0;

        right.asum = rt.changeTag * (right.r - right.l + 1);
        right.iisum = (right.l + right.r) * (right.r - right.l + 1) / 2 * rt.changeTag;
        right.changeTag = rt.changeTag, right.addTag = 0;

        rt.changeTag = inf;
    }
    if (rt.addTag != 0) {
        left.asum += rt.addTag * (left.r - left.l + 1);
        left.iisum += (left.l + left.r) * (left.r - left.l + 1) / 2 * rt.addTag;
        left.addTag += rt.addTag;

        right.asum += rt.addTag * (right.r - right.l + 1);
        right.iisum += (right.l + right.r) * (right.r - right.l + 1) / 2 * rt.addTag;
        right.addTag += rt.addTag;

        rt.addTag = 0;
    }
}

void build(ll u, ll l, ll r) {
    if (l > r) return;
    if (l == r) {
        tr[u] = {l, r, a[l], a[l] * l, inf, 0};
        return;
    }
    tr[u] = {l, r, 0, 0, inf, 0};
    ll mid = (l + r) >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void modify(ll u, ll l, ll r, ll change, ll add) {
    if (l > r) return;
    if (tr[u].l >= l && tr[u].r <= r) {
        if (change != inf) {
            tr[u].asum = (tr[u].r - tr[u].l + 1) * change;
            tr[u].iisum = (tr[u].l + tr[u].r) * (tr[u].r - tr[u].l + 1) / 2 * change;
            tr[u].changeTag = change;
            tr[u].addTag = 0;
        }
        if (add != 0) {
            tr[u].asum += (tr[u].r - tr[u].l + 1) * add;
            tr[u].iisum += (tr[u].l + tr[u].r) * (tr[u].r - tr[u].l + 1) / 2 * add;
            tr[u].addTag += add;
        }
        return;
    }

    pushdown(u);
    ll mid = (tr[u].l + tr[u].r) >> 1;
    if (l <= mid) modify(u << 1, l, r, change, add);
    if (r > mid) modify(u << 1 | 1, l, r, change, add);
    pushup(u);
}

ll queryAsum(ll u, ll l, ll r) {
    if (l > r) return 0;
    if (tr[u].l >= l && tr[u].r <= r) return tr[u].asum;
    pushdown(u);
    ll mid = (tr[u].l + tr[u].r) >> 1;
    ll ans = 0;
    if (l <= mid) ans = ans + queryAsum(u << 1, l, r);
    if (r > mid) ans = ans + queryAsum(u << 1 | 1, l, r);
    return ans;
}

ll queryIisum(ll u, ll l, ll r) {
    if (l > r) return 0;
    if (tr[u].l >= l && tr[u].r <= r) return tr[u].iisum;
    pushdown(u);
    ll mid = (tr[u].l + tr[u].r) >> 1;
    ll ans = 0;
    if (l <= mid) ans = ans + queryIisum(u << 1, l, r);
    if (r > mid) ans = ans + queryIisum(u << 1 | 1, l, r);
    return ans;
}

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    ll n, q;
    cin >> n >> q;
    for (ll i = 1; i <= n; ++i) cin >> a[i];
    build(1, 1, n);
    for (int cas = 1; cas <= q; ++cas) {
        ll op, l, r;
        cin >> op >> l >> r;
        if (l > r) swap(l, r);
        if (op == 1) {
            ll x;
            cin >> x;
            modify(1, l, r, inf, x);
        } else if (op == 2) {
            ll x;
            cin >> x;
            modify(1, l, r, x, 0);
        } else if (op == 3) {
            ll asum = queryAsum(1, l, r);
            ll iisum = queryIisum(1, l, r);
            bool flag = false;
            if (asum == 0 && iisum == 0) flag = true;
            else if (asum && iisum % asum == 0) {
                ll d = iisum / asum;
                if (l <= d && d <= r) flag = true;
            }
            if (flag) {
                cout << "Yes\n";
            } else {
                cout << "No\n";
            }
        }
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值