ICode9

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

CF643G Choosing Ads

2022-08-31 21:03:38  阅读:148  来源: 互联网

标签:cnt Ads val int tr num CF643G Choosing include


传送门


思路

先考虑一下 \(p > 50\) 的情况

这时候就是求“绝对众数”

一个方法就是用“摩尔投票”法

方法就是:每次将不同的两个数去掉,剩下的那种数就是绝对众数(这是保证在有的情况下,才能求出正确的众数)

再考虑 \(20\le p \le 50\) 时,其实我们可以维护 \(\lfloor\frac{p}{100}\rfloor\) 个这样的数

当新增一个数时,我们与维护的数进行比较:如果维护的数有与新增的数相同的,就将这种数的“个数”+1;否则,我们就所有维护的数的“个数”都减一,如果出现 \(-1\) 的,就用新增的数替代它

有区间赋值和询问,采用线段树维护即可

有个辣鸡因为把一个 \(i\) 打成 \(j\) 导致调了接近一个下午,我不说是谁


代码

#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#define LL long long
#define FOR(i, x, y) for(int i = (x); i <= (y); i++)
#define ROF(i, x, y) for(int i = (x); i >= (y); i--)
#define PFOR(i, x) for(int i = he[x]; i; i = r[i].nxt)
inline int reads()
{
    int sign = 1, re = 0; char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') sign = -1; c = getchar();}
    while('0' <= c && c <= '9'){re = re * 10 + (c - '0'); c = getchar();}
    return sign * re;
}
int n, m, p; int cnt;
struct Node
{
    int val[6], cnt[6], num; bool tag;
}tr[600005];
#define ls (now << 1)
#define rs ((now << 1) | 1)
inline void down(int now, int l, int r)
{
    if(tr[now].tag)
    {
        int mid = (l + r) >> 1;
        tr[ls].tag = tr[rs].tag = 1;
        tr[ls].num = tr[rs].num = 1;
        tr[ls].val[1] = tr[rs].val[1] = tr[now].val[1];
        tr[ls].cnt[1] = mid - l + 1, tr[rs].cnt[1] = r - mid;
        tr[now].tag = 0;
    }
}
inline Node merge(Node a, Node b)
{
    FOR(i, 1, a.num)
    {
        bool same = 0;
        FOR(j, 1, b.num)
            if(a.val[i] == b.val[j])
            {
                b.cnt[j] += a.cnt[i];
                same = 1;
                break;
            }
        if(same) continue;
        if(b.num < p)
        {
            ++b.num,
            b.val[b.num] = a.val[i],
            b.cnt[b.num] = a.cnt[i];
            continue;
        }
        int id = 1;
        FOR(j, 2, b.num)
            if(b.cnt[j] < b.cnt[id]) id = j;
        if(b.cnt[id] < a.cnt[i])
            std::swap(a.val[i], b.val[id]), std::swap(a.cnt[i], b.cnt[id]);
        FOR(j, 1, b.num)
            b.cnt[j] -= a.cnt[i];
    }
    b.tag = 0;
    return b;
}
void build(int now, int l, int r)
{
    if(l == r)
    {
        tr[now].val[1] = reads();
        tr[now].num = tr[now].cnt[1] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(ls, l, mid), build(rs, mid + 1, r);
    tr[now] = merge(tr[ls], tr[rs]);
}
void modify(int now, int l, int r, int L, int R, int val)
{
    if(L <= l && r <= R)
    {
        tr[now].val[1] = val;
        tr[now].num = 1;
        tr[now].cnt[1] = r - l + 1;
        tr[now].tag = 1;
        return;
    }
    down(now, l, r);
    int mid = (l + r) >> 1;
    if(L <= mid) modify(ls, l, mid, L, R, val);
    if(mid < R) modify(rs, mid + 1, r, L, R, val);
    tr[now] = merge(tr[ls], tr[rs]);
}
Node query(int now, int l, int r, int L, int R)
{
    if(L <= l && r <= R) return tr[now];
    down(now, l, r);
    int mid = (l + r) >> 1;
    if(R <= mid) return query(ls, l, mid, L, R);
    if(mid < L) return query(rs, mid + 1, r, L, R);
    return merge(query(ls, l, mid, L, R), query(rs, mid + 1, r, L, R));
}
signed main()
{
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    n = reads(), m = reads(), p = reads(), p = 100 / p;
    build(1, 1, n);
    FOR(i, 1, m)
    {
        int ty = reads(), l = reads(), r = reads();
        if(ty == 1)
        {
            int val = reads();
            modify(1, 1, n, l, r, val);
        }
        else
        {
            cnt++;
            Node ans = query(1, 1, n, l, r);
            printf("%d ", ans.num);
            FOR(j, 1, ans.num) printf("%d ", ans.val[j]);
            puts("");
        }
    }
    return 0;
}

标签:cnt,Ads,val,int,tr,num,CF643G,Choosing,include
来源: https://www.cnblogs.com/zuytong/p/16644472.html

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

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

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

ICode9版权所有