ICode9

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

2022.8.8 心态爆炸记录

2022-08-09 01:04:41  阅读:337  来源: 互联网

标签:10 le 爆炸 心态 贿赂 int maxn 2022.8 id


Preface

又是颓废的一天!

Content

[CF1251E2]Voting(Hard Version)

一共有 \(n\) 个选民,你可以付出 \(p_i\)​ 的代价让第 \(i\) 个选民为你投票,或者,在为你投票的人数达到 \(m_i\)​ 时,他会主动为你投票而不用你付出任何代价。

问得到所有选民投票的最小代价。

\(1\le n \le 2\times 10^5,1\le p_i\le 10^9,0\le m_i\lt n\)。

神仙贪心,思路难想,代码也难理解。

这道题里肯定就不能延续 Easy Version 的 DP 了,那这个问题大概率就是贪心。

首先要发现若干个性质:

  1. 如果已经确定要花钱收买一些人,那么肯定是在一开始就收买他们。(这点一定要记牢,我们接下来贿赂的人并不是按处理顺序,而是一开始就先贿赂好)

  2. 基于 Easy Version 的思路,把 \(m\) 升序排序,那么处理 \(m_i=x\) 时,\(m=1\sim x-1\) 的人一定都已经投了票,否则一定更劣。至于是收买还是跟风我们不知道,也不需要知道。

性质 1 不难理解,至于性质 2,我的理解是:这是基于性质 1 的推断。

当我们处理到 \(m_i=x\) 的时候,肯定是希望这些人尽可能地跟风,减少花费。

那这就要求已经投过的人尽量地多。

如果 \(m_i\) 的人无法跟风,那 \(m\gt m_i=x\) 的人肯定更没法跟风。

所以只能考虑 \(m\lt m_i=x\) 的人,先让他们都投了,如果此时还没法让 \(m_i\) 跟风,那就只能在 \(m_i\ge x\) 的人里选一些贿赂。

还是要记住,我们贿赂的这些人是在一开始就贿赂了的。

综上,设计出一个贪心算法:

std::vector 存储 \(m_i\) 每种取值对应的 \(p_i\)。

倒序遍历 \(0\sim n-1\),如果后面买的人加上前面所有人的数量仍然小于当前的 \(m\),就从后面没买的人里选择若干个贿赂。

时间复杂度 \(O(N\log N)\),描述得很乱,建议参考代码。

Code

// Problem: CF1251E2 Voting (Hard Version)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF1251E2
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
using namespace std;
const int maxn = 2e5 + 5;
typedef long long ll;
int n;
vector<ll> G[maxn];
multiset<ll> s;
void work() {
    scanf("%d",&n);
    for(int i = 0;i < n;++ i)G[i].clear();
    s.clear();
    for(int i = 1;i <= n;++ i) {
        int x;
        ll y;
        scanf("%d %lld",&x,&y);
        G[x].pb(y);
    }
    int tot = n,cur = 0;
    //cur:当前买了多少个
    //tot:前面已经有多少人投了
    ll ans = 0;
    for(int i = n - 1;~ i;-- i) {
        if(G[i].empty())continue ;
        tot -= G[i].size();
        for(auto& v : G[i]) {
            s.insert(v);
        }
        for(;cur < i - tot;++ cur) {
            ans += *s.begin();
            s.erase(s.begin());
        }
    }
    printf("%lld\n",ans);
    return ;
}
int main() {
    int T;
    scanf("%d",&T);
    while(T --)work();
    return 0;
}

[CF853C]Boredom

调了 \(\infin\) 年调不出来,心态爆炸,于是直接对着 7KByte 大佬的题解写,虽然有些地方无法理解,但我不管,摆烂了,不写题解,有兴趣可以看看 7KByte 大佬的题解。只放代码。

Code

// Problem: CF853C Boredom
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF853C
// Memory Limit: 500 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
struct query {
    int x,y,l,r,id,v;
    query() {
        x = y = l = r = id = v = 0;
    }
    query(int x,int l,int r,int id,int v):x(x),l(l),r(r),id(id),v(v){}
}Q[maxn];
typedef long long ll;
ll ans[maxn];
int c[maxn],a[maxn];
int n,m;
int lowbit(int x) {
    return x & -x;
}
void add(int x,int y) {
    for(;x <= n;x += lowbit(x))c[x] += y;
    return ;
}
int Query(int x) {
    int ans = 0;
    for(;x;x -= lowbit(x))ans += c[x];
    return ans;
}
int b[maxn];
void rev() {
    for(int i = 1;i <= n;++ i)b[a[i]] = i;
    for(int i = 1;i <= n;++ i)a[i] = b[i];
    for(int i = 1;i <= m;++ i) {
        int x = Q[i].x,y = Q[i].y;
        Q[i].x = n + 1 - Q[i].r;
        Q[i].y = n + 1 - Q[i].l;
        Q[i].l = x;
        Q[i].r = y;
    }
    return ;
}
void calc() {
    sort(Q + 1 , Q + 1 + m , [&](const query& p,const query& q) {
        return p.l < q.l;
    });
    memset(c , 0 , sizeof(c));
    for(int i = 1,j = 1;i <= m;++ i) {
        for(;j < Q[i].l;++ j) {
            add(a[j] , 1);
        }
        int cur = Query(Q[i].x - 1);
        ans[Q[i].id] -= 1ll * (j - 1) * (j - 2) / 2 - 1ll * cur * (cur - 1) / 2ll; 
    }
    return ;
}
int main() {
    scanf("%d %d",&n,&m);
    for(int i = 1;i <= n;++ i)scanf("%d",&a[i]);
    for(int i = 1;i <= m;++ i) {
        scanf("%d %d %d %d",&Q[i].l,&Q[i].x,&Q[i].r,&Q[i].y);
        Q[i].id = i;
        ans[i] = 1ll * n * (n - 1) / 2ll;
    }
    calc();
    rev();
    calc();
    rev();
    calc();
    rev();
    calc();
    for(int i = 1;i <= m;++ i)printf("%lld\n",ans[i]);
    return 0;
}

[CF768D]Jon and Orbs

无数个物品,种类有 \(N\) 种,每天可以随机取其中一个。

\(Q\) 次询问,询问将 \(N\) 种物品都取到的概率不小于 \(\frac{p}{2000}\) 的最小天数。

\(1 \le N,Q,p \le 10^3\)。

简单题,就是洛谷翻译的题面让我晕了好久。

设 \(f(i,j)\) 表示 \(i\) 天取到 \(j\) 种物品的概率。

初始状态:\(f(0,0)=1\)。

状态转移方程:\(f(i,j)=f(i-1,j)\times \frac{j}{n}+f(i-1,j-1)\times \frac{n-j+1}{n}\)。

在 \(N,p\) 均取极值的情况下,实测得出约为 \(7500\),数组开 \(10^4\times 10^3\) 即可。

每次询问直接暴力查找就行。

Code

标签:10,le,爆炸,心态,贿赂,int,maxn,2022.8,id
来源: https://www.cnblogs.com/Royaka/p/16564515.html

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

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

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

ICode9版权所有