首页 > 其他分享 >闲话 22.10.23

闲话 22.10.23

时间:2022-10-23 19:46:35浏览次数:107  
标签:ch bel get int 闲话 rep 23 22.10 que

闲话

打”细节”,然后输入了“xj”,第一候选字是“星界”
aaaa我想听情绪的歌了aaaa
奇怪的戒断反应增加了

smtwy:我手机里有一万多张二次元图
我:您是在什么精神状态下做出这种事的

打了cf

Runtime error on pretest 2

哦我vector多弹了个元素
改掉应该就没事了

Wrong answer on pretest 2
Wrong answer on pretest 2
Wrong answer on pretest 2

azazazazaz
于是就这么在C2吃了四发罚时
不要死磕已经知道fake的思路(

[最近脑子里一直循环Aster的pv,所以今天推的就是Aster了!]
[这pv显然是没法放在这的,可以自行右转b站查询]

随机刷题

AGC018C

有 \(x+y+z\) 个人,第 \(i\) 个人有 \(A_i\) 个金币,$ B_i$ 个银币,\(C_i\) 个铜币。

选出 \(x\) 个人获得其金币,选出 \(y\) 个人获得其银币,选出 \(z\) 个人获得其铜币,在不重复选某个人的情况下,最大化获得的币的总数。

\(x+y+z\le 1e5\)。

可反悔贪心。

首先我们先假设从所有人那里都拿了金币。随后将一个人拿银币的收益转换成 \(B_i - A_i\),拿铜币的收益转换成 \(C_i - A_i\)。
然后我们就可以转化成 \(n\) 个二元组 \((a_i, b_i)\),从中里选择 \(y\) 个加入 \(a_i\),选出 \(z\) 个加入 \(b_i\),最后的总价值最大是多少。

考虑通过一些方式产生一个断点,使得在这前面的点都选 \(a_i\),在这后面的点都选 \(b_i\)。
假设 \((a_i, b_i)\) 选 \(a_i\),\((a_j,b_j)\) 选 \(b_j\),并且交换后答案不会更优,则有

\[a_i + b_j > b_i + a_j \]

移项后得到

\[a_i - b_i > a_j - b_j \]

通过此关键字排序产生断点即可。

然后处理每个点前缀中选 \(y\) 个,后缀中选 \(z\) 个的最大花费,最后 \(O(n)\) 枚举即可。
处理前后缀时使用堆维护当前所选元素中的最小值。总时间复杂度 \(O(n\log n)\)。

细节:不要从 \(1\) 开始枚举要不然会吃很多次罚时

code
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
char buf[1<<21], *p1 = buf, *p2 = buf;  inline char getc() { return (p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++); }
#define getchar getc
template <typename T> inline void get(T & x){
	x = 0; char ch = getchar(); bool f = 0; while (ch < '0' or ch > '9') f = f or ch == '-',  ch = getchar();
	while (ch >= '0' and ch <= '9') x = (x<<1) + (x<<3) + (ch^48), ch = getchar(); f and (x = -x);
} template <typename T, typename ... Args> inline void get(T & x, Args & ... _Args) { get(x); get(_Args...); }
#define rep(i,a,b) for (register int i = (a), i##_ = (b) + 1; i < i##_; ++i)
#define pre(i,a,b) for (register int i = (a), i##_ = (b) - 1; i > i##_; --i)
#define int long long
const int N = 1e5 + 10; 
int n, x, y, z, sum1[N], sum2[N], ans;

struct nin {
    int a, b, c;
    int b_a, c_a;
    bool operator < (const nin & s) const {
        return b_a - c_a > s.b_a - s.c_a;
    }
} a[N];

priority_queue <int, vector<int>, greater<> > que;

signed main() {
	get(x, y, z); n = x + y + z;
    rep(i,1,n) get(a[i].a, a[i].b, a[i].c), a[i].b_a = a[i].b - a[i].a, a[i].c_a = a[i].c - a[i].a, ans += a[i].a;
    sort(a+1, a+1+n);

    int now = 0;
    rep(i,1,n) {
        if (que.size() < y) now += a[i].b_a, que.push(a[i].b_a);
        else if (que.top() < a[i].b_a) {
            now += a[i].b_a - que.top();
            que.pop(); que.push(a[i].b_a);
        } sum1[i] = now;
    } 
    
    now = 0; while (que.size()) que.pop();
    pre(i,n,1) {
        if (que.size() < z) now += a[i].c_a, que.push(a[i].c_a);
        else if (que.top() < a[i].c_a) {
            now += a[i].c_a - que.top();
            que.pop(); que.push(a[i].c_a);
        } sum2[i] = now;
    } 
    
    now = - (1e9 + 19);
    rep(i,y,n-z) now = max(now, ans + sum1[i] + sum2[i+1]);
    cout << now << endl;
}



CF730I

有 \(n\) 个学生,每人有两种技能,分别是 \(a,b\) 表示编程能力和运动能力。你需要将他们分为两个团队分别参加编程比赛和体育比赛,编程团队有 \(p\) 人,体育团队有 \(s\) 人,一个学生只能参加其中一项。每个团队的力量是其成员在对应领域能力总和,请问如何分配能使得两个团队的能力和最大?输出最大能力和与任意一种方案。

原译者没分段不是我的问题

首先贪心地让 \(a\) 最大的 \(p\) 个人进入编程团队,然后进行 \(s\) 次抉择,在保证编程团队人数不减的情况下让一个人加入体育团队。
两种情况:

  1. 将一个不在团队里的人放入体育团队,增加 \(b_i\)
  2. 将一个原来在编程团队里的人放入体育团队并将一个不在团队里的人放入编程团队,增加 \(b_i - a_i + a_j\)

维护 \(a_i,b_i,b_i-a_i\) 的最大值,每次取最优决策执行即可。
使用三个堆,总时间复杂度 \(O(n \log n)\)。

code
#include <bits/stdc++.h>
using namespace std;
    char buf[1<<21], *p1 = buf, *p2 = buf;  inline char getc() { return (p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++); }
    #define getchar getc
template <typename T> inline void get(T & x){
	x = 0; char ch = getchar(); bool f = 0; while (ch < '0' or ch > '9') f = f or ch == '-',  ch = getchar();
	while (ch >= '0' and ch <= '9') x = (x<<1) + (x<<3) + (ch^48), ch = getchar(); f and (x = -x);
} template <typename T, typename ... Args> inline void get(T & x, Args & ... _Args) { get(x); get(_Args...); }
#define rep(i,a,b) for (register int i = (a), i##_ = (b) + 1; i < i##_; ++i)
#define pre(i,a,b) for (register int i = (a), i##_ = (b) - 1; i > i##_; --i)
const int N = 3e5 + 10;
int n, x, y, ans;
int a[N], b[N];
pair<int,int> w[N];
int bel[N];

priority_queue <pair<int,int> > q1, q2, q3;
#define insert(u) \
{\
    if (bel[u] == 0) q1.emplace(b[u], u), q2.emplace(a[u], u);\
    else if (bel[u] == 1) q3.emplace(b[u] - a[u], u);\
}

signed main() {
	get(n, x, y);
    rep(i,1,n) get(a[i]), w[i] = {a[i], i};
    rep(i,1,n) get(b[i]);
    sort(w+1, w+1+n, greater<>());
    rep(i,1,x) ans += w[i].first, bel[w[i].second] = 1;
    rep(i,1,n) insert(i);
    rep(i,1,y) {
        int mx = -1e9, typ = 0;
        while (!q1.empty() and bel[q1.top().second] != 0) q1.pop();
        while (!q2.empty() and bel[q2.top().second] != 0) q2.pop();
        while (!q3.empty() and bel[q3.top().second] != 1) q3.pop();
        if (q1.size() and mx < q1.top().first) mx = q1.top().first, typ = 1;
        if (q2.size() and q3.size() and mx < q2.top().first + q3.top().first) mx = q2.top().first + q3.top().first, typ = 2;
        assert(typ > 0);
        ans += mx;
        if (typ == 1) { bel[q1.top().second] = 2; insert(q1.top().second); }
        else { bel[q2.top().second] = 1, bel[q3.top().second] = 2; insert(q2.top().second); insert(q3.top().second); }
    }
    cout << ans << endl;
    rep(i,1,n) if (bel[i] == 1) cout << i << ' '; cout << endl;
    rep(i,1,n) if (bel[i] == 2) cout << i << ' '; cout << endl;
}



CF802O

\(n\) 道题, 第 \(i\) 天可以花费 \(a_i\) 准备一道题, 花费 \(b_i\) 打印一道题, 每天最多准备一道, 最多打印一道, 准备的题可以留到以后打印, 求最少花费使得准备并打印 \(k\) 道题。

\(n \le 5\times 10^5\)。

wqs二分。

考虑我们令准备一道题的花费减少 \(\text{mid}\)。只有在准备并打印一道题的花费小于 \(0\) 时我们才计入答案。然后可以计算出对于 \(\text{mid}\) 共能够完成多少道题。

当完成题数刚好等于 \(m\) 时得到答案。

code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#ifdef ONLINE_JUDGE
    char buf[1<<21], *p1 = buf, *p2 = buf;  inline char getc() { return (p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++); }
    #define getchar getc
#endif
template <typename T> inline void get(T & x){
	x = 0; char ch = getchar(); bool f = 0; while (ch < '0' or ch > '9') f = f or ch == '-',  ch = getchar();
	while (ch >= '0' and ch <= '9') x = (x<<1) + (x<<3) + (ch^48), ch = getchar(); f and (x = -x);
} template <typename T, typename ... Args> inline void get(T & x, Args & ... _Args) { get(x); get(_Args...); }
#define rep(i,a,b) for (register int i = (a), i##_ = (b) + 1; i < i##_; ++i)
#define pre(i,a,b) for (register int i = (a), i##_ = (b) - 1; i > i##_; --i)
const int N = 5e5 + 10; using ll = long long;
int n, k, ret, cnt, a[N], b[N], cb[N];

void check(int val){
    priority_queue <pair<ll, int>, vector<pair<ll, int> >, greater<> > que;
    ret = cnt = 0; int dlt;
    rep(i,1,n) {
        que.emplace(a[i] - val, 1);
        dlt = b[i] + que.top().first;
        if (dlt < 0) {
            ret += dlt; cnt += que.top().second;
            que.pop();
            que.emplace(-b[i], 0);
        }
    } 
}

signed main() {
	get(n, k); rep(i,1,n) get(a[i]); rep(i,1,n) get(b[i]);
    int l = 0, r = 2e9, mid;
    while (l < r) {
        mid = l + r >> 1;
        check(mid);
        if (cnt == k) { cout << ret + k * mid; return 0; }
        else if (cnt > k) r = mid - 1;
        else l = mid + 1;
    } 
    cout << (ret / cnt + mid) * k;
}



K-query

给定一个长度为 \(n\) 的序列 \(a_i\)。

有 \(q\) 次询问 \((l,r,k)\):输出 \(a_l\) 到 \(a_r\) 中大于 \(k\) 的数字的个数。

区间允许离线的信息,考虑莫队维护。

左端点分块,块长设 \(\frac {n}{\sqrt q}\) 即可。
以此块长分块可以得到端点移动次数 \(O(q\sqrt n + q\sqrt q)\)。分析可得此为最优选择。
右端点奇偶化排序降低常数。

我们发现维护的信息只需要相对大小关系不变即可,因此可以离散化使得值域落在 \(O(n)\) 范围内。

考虑莫队不平衡的信息维护情况。
在整个程序中,我们一共需要移动端点 \(O(q \sqrt q)\) 次,但只需要查询 \(O(q)\) 次。这启发我们采用根号平衡思想,设计一种 \(O(1)\) 修改 \(O(\sqrt n)\) 查询的数据结构。

考虑值域分块。对值域分块,长度为 \(O(\sqrt n)\),维护单点数量和块内加和。在加入时修改所在点的值与所在块的加和,查询时扫描其所在块内其后元素,并扫描所在块后的块即可。

总时间复杂度 \(O(q \sqrt q)\)。

实现时可以只离散化 \(a_i\),\(k\) 值在需要时查询 \(\text{upper_bound}\) 的前驱即可。

code
#include <bits/stdc++.h>
using namespace std;
#ifdef ONLINE_JUDGE
    char buf[1<<21], *p1 = buf, *p2 = buf;  inline char getc() { return (p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, 1<<21, stdin), p1 == p2) ? EOF : *p1++); }
    #define getchar getc
#endif
template <typename T> inline void get(T & x){
	x = 0; char ch = getchar(); bool f = 0; while (ch < '0' or ch > '9') f = f or ch == '-',  ch = getchar();
	while (ch >= '0' and ch <= '9') x = (x<<1) + (x<<3) + (ch^48), ch = getchar(); f and (x = -x);
} template <typename T, typename ... Args> inline void get(T & x, Args & ... _Args) { get(x); get(_Args...); }
#define rep(i,a,b) for (register int i = (a), i##_ = (b) + 1; i < i##_; ++i)
#define pre(i,a,b) for (register int i = (a), i##_ = (b) - 1; i > i##_; --i)
const int N = 3e5 + 10;
int n, q, siz, bel[N], a[N], lsh[N], hrt, ans[N];

struct query {
    int l, r, k, id;
    bool operator < (const query & b) const {
        if (bel[l] != bel[b.l]) return l < b.l;
        if (bel[l] & 1) return r > b.r;
        return r < b.r;
    }
} qy[N];

struct sqrt_tech {
    int L, siz, bel[N], lp[N], rp[N], cntpts[N], cntblk[N];
    void init(int _l) {
        L = _l;
        siz = sqrt(L);
        rep(i,1,L) {
            bel[i] = (i - 1) / siz + 1;
            if (bel[i] != bel[i-1]) lp[bel[i]] = i, rp[bel[i-1]] = i-1;
        } rp[bel[L]] = L;
    }
    
    void add(int val, int k) {
        cntpts[val] += k ; cntblk[bel[val]] += k;
    }

    int qry(int k) {
        int ret = 0;
        rep(i,k+1,rp[bel[k]]) ret += cntpts[i];
        rep(i,bel[k]+1,bel[L]) ret += cntblk[i];
        return ret;
    }
} st;

signed main() {
	get(n); rep(i,1,n) get(a[i]), lsh[++hrt] = a[i];
    get(q); rep(i,1,q) get(qy[i].l, qy[i].r, qy[i].k), qy[i].id = i;
    siz = n / sqrt(q);
    rep(i,1,n) bel[i] = (i - 1) / siz + 1;
    sort(qy + 1, qy + 1 + q);
    sort(lsh+1, lsh+1+hrt); hrt = unique(lsh+1, lsh+1+hrt) - lsh - 1;
    rep(i,1,n) a[i] = lower_bound(lsh+1, lsh+1+hrt, a[i]) - lsh; 
    st.init(hrt);

    for (int i(1), l(1), r(0); i <= q; ++ i) {
        while (l > qy[i].l) st.add(a[-- l], 1);
        while (r < qy[i].r) st.add(a[++ r], 1);
        while (l < qy[i].l) st.add(a[l ++], -1);
        while (r > qy[i].r) st.add(a[r --], -1);
        int tmp = upper_bound(lsh+1, lsh+1+hrt, qy[i].k) - lsh - 1;
        ans[qy[i].id] = st.qry(tmp);
    } 
    
    rep(i,1,q) cout << ans[i] << '\n';
}

Backup Files

双倍经验。昨天数据备份那题。

标签:ch,bel,get,int,闲话,rep,23,22.10,que
From: https://www.cnblogs.com/joke3579/p/chitchat221023.html

相关文章

  • 2022-2023-1 20221311 《计算机基础与程序设计》第八周学习总结
    班级链接:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业要求:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK08作业目标:学习计算机科学概论第9章《C语......
  • 周总结--20221023
    代码实战篇要求.按照软件开发⽬录规范创建出完整⽬录.核⼼逻辑⽂件中编写调用⽤户注册登录功能,.注册功能要有校验⽤户是否存在和数据保存的功能.common.py⽂件中编写......
  • 2022.10.22
    总算能抽出点时间出去玩玩了睡完午觉,大概下午三点起床,又磨磨蹭蹭到4点。看了看等车来和地图,决定先坐15路到官渡桥东,然后坐5路车直达等车等到4点半,又坐车坐了一个多小时,大......
  • 2022-2023 20221319《计算机基础与程序设计》第八周学习总结
    作业信息这个作业属于那个班级:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业要求:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK06作业目标:《计算......
  • 2022-2023-1 20221324《计算机基础与程序设计》第八周学习总结
    ##作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#W......
  • 2022-2023-1 20221405 《计算机基础与程序设计》 第八周学习总结
    作业信息这个作业属于哪个课程2022-2023-1-计算机基础与程序设计这个作业要求在哪里2022-2023-1计算机基础与程序设计第八周作业这个作业的目标数组与链表......
  • 10.23学习总结
    10.23学习总结目录10.23学习总结一、常见内置函数二、可迭代对象三、迭代器对象四、生成器对象五、for循环的本质六、异常捕获七、异常捕获语法八、迭代取值与索引取值的......
  • 新版PS2023保姆级安装教程2022安装
    PS2023Windows安装教程退出安全软件①:下载PS2023安装包②:打开下载好的文件,鼠标右键把安装包解压③:打开解压好的"PS24.0.0"文件夹,找到并选中"Set-up",鼠标右键点击"以管......
  • PS2023下载安装保姆级教程中文汉化完整版
    PS2023Windows安装教程退出安全软件①:下载PS2023安装包②:打开下载好的文件,鼠标右键把安装包解压③:打开解压好的"PS24.0.0"文件夹,找到并选中"Set-up",鼠标右键点击"以管理......
  • 【ps下载与安装】Adobe Photoshop 2022 for Mac v23.5 中文永久版下载 Ps图像编辑软件
    AdobePhotoshop2022mac破解版,是一款Ps图像编辑软件,同时支持M1/M2芯片和Intel芯片安装,此主要的更新包括多个新增和改进的功能,例如改进的对象选择工具,其悬停功能可预览选......