首页 > 其他分享 >『模拟赛』多校A层冲刺NOIP2024模拟赛09

『模拟赛』多校A层冲刺NOIP2024模拟赛09

时间:2024-10-20 11:01:07浏览次数:1  
标签:ch int 09 lx qr 模拟 dis NOIP2024 define

Rank

还行

image

A. 排列最小生成树 (pmst)

签,有点可惜。

考虑连 \(i\) 与 \(i+1\) 时,所有边边权都是小于 \(n\) 的,因此我们只考虑边权小于 \(n\) 的边即可。因为边权为 \(|p_i-p_j|\times|i-j|\),所以只考虑 \(|p_i-p_j|\lt \sqrt{n}\) 和 \(|i-j|\lt \sqrt{n}\) 的情况,每个点只用连 \(\sqrt{n}\) 条边,复杂度为 \(\mathcal{O(n\sqrt{n}\log n)}\)。桶记录每一条边可以优化掉排序,并查集按秩合并优化,然后就过了。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define P_B(x) push_back(x)
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
const int Ratio = 0;
const int N = 5e4 + 5;
int n, cnt;
int a[N], fx[N], p[N], siz[N];
ll ans;
vector<pii> e[N];
namespace Wisadel
{
    inline int Wfind(int x)
    {
        if(x == fx[x]) return x;
        return fx[x] = Wfind(fx[x]);
    }
    short main()
    {
        freopen("pmst.in", "r", stdin) , freopen("pmst.out", "w", stdout);
        n = qr;
        fo(i, 1, n) a[i] = qr, fx[i] = i, p[a[i]] = i, siz[i] = 1;
        for(int i = 1; i * i <= n; i++) fo(j, 1, n - i)
        {
            int zc = 1ll * abs(a[j + i] - a[j]) * i;
            if(zc < n) e[zc].P_B(M_P(j, j + i));
        }
        for(int i = 1; i * i <= n; i++) fo(j, 1, n - i)
        {
            int zc = 1ll * abs(p[j] - p[j + i]) * i, zd = 1ll * abs(p[j] - p[j + i]);
            if(1ll * zd * zd > 1ll * n && zc < n) e[zc].P_B(M_P(p[j], p[j + i]));
        }
        fo(i, 1, n) if(e[i].size())
        {
            for(pii j : e[i])
            {
                int _ = Wfind(j.fi), __ = Wfind(j.se);
                if(_ != __)
                {
                    if(siz[_] >= siz[__])
                    {
                        siz[_] += siz[__];
                        fx[__] = _;
                    }
                    else
                    {
                        siz[__] += siz[_];
                        fx[_] = __;
                    }
                    ans += i;
                }
            }
        }
        printf("%lld\n", ans);
        return Ratio;
    }
}
signed main(){return Wisadel::main();}

B. 卡牌游戏 (cardgame)

真正的签,不知道跟 T2 换位置有什么深意。

发现卡牌数量互质情况下每一对牌都会 pk 一次,当不互质时,会重复 \(gcd(n,m)\) 次完全一样的对局,此时对于一张牌显然不会与其余所有牌 pk,手模发现它只会和从它开始与它间隔 \(gcd(n,m) - 1\) 个的牌 pk,然后 \(\mathcal{O(n)}\) 跑一遍就做完了。

为了方便,我分成了 \(n\le m\) 和 \(n\gt m\) 两种情况做。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 1e5 + 5, M = 5e5;
int n, m;
int a[N], b[N];
ll win, lose, ping;
vector<int> sum[N];
namespace Wisadel
{
    short main()
    {
        freopen("cardgame.in", "r", stdin) , freopen("cardgame.out", "w", stdout);
        n = qr, m = qr;
        fo(i, 1, n) a[i] = qr;
        fo(i, 1, m) b[i] = qr;
        int gcd = __gcd(n, m);
        if(n <= m)
        {
            fo(len, 1, gcd)
            {
                for(int i = len; i <= m; i += gcd)
                    sum[len].P_B(b[i]);
                sort(sum[len].begin(), sum[len].end());
            }
            fo(i, 1, n)
            {
                int zu = i % gcd; if(zu == 0) zu = gcd;
                int zc = lower_bound(sum[zu].begin(), sum[zu].end(), a[i]) - sum[zu].begin();
                zc++;
                win += 1ll * (zc - 1);
                int zd = upper_bound(sum[zu].begin(), sum[zu].end(), a[i]) - sum[zu].begin();
                zd++;
                ping += 1ll * (zd - zc);
                lose += 1ll * (m / gcd - zd + 1);
            }
            win *= gcd, ping *= gcd, lose *= gcd;
        }
        else
        {
            fo(len, 1, gcd)
            {
                for(int i = len; i <= n; i += gcd)
                    sum[len].P_B(a[i]);
                sort(sum[len].begin(), sum[len].end());
            }
            fo(i, 1, m)
            {
                int zu = i % gcd; if(zu == 0) zu = gcd;
                int zc = lower_bound(sum[zu].begin(), sum[zu].end(), b[i]) - sum[zu].begin();
                zc++;
                lose += 1ll * (zc - 1);
                int zd = upper_bound(sum[zu].begin(), sum[zu].end(), b[i]) - sum[zu].begin();
                zd++;
                ping += 1ll * (zd - zc);
                win += 1ll * (n / gcd - zd + 1);
            }
            win *= gcd, ping *= gcd, lose *= gcd;
        }
        printf("%lld\n%lld\n%lld\n", win, lose, ping);
        return Ratio;
    }
}
signed main(){return Wisadel::main();}

C. 比特跳跃 (jump)

又一道魔改最短路。

  • \(s=1\) 时,发现除了最大点为 \(11\cdots 1_{(2)}\) 之外的情况,都能找到一个点与一个数的位与值为 0,所以特判 \(n\) 即可。

  • \(s=2\) 时,发现 \(a\oplus b+b\oplus c=a\oplus c\),因此我们可以省掉 \(a\rightarrow c\) 这条边,即每个点只与与其一位不一样的点连边即可,每个点只有 \(\log n\) 条。

  • \(s=3\) 时,发现 \((a|b) + (b|c) \ge (a|c)\)。对于点 \(i\) 边权最少是 \(i\)。我们考虑给每个点多映射一个虚点,点到虚点的边权为 \(k\times i\),虚点到实点边权为 \(0\),然后在虚点上连边,同样只与与其一位不一样的点连边,若该点该位为 1 那么没有额外边权,否则边权为 \(k\times 2^i\) (\(i\) 为位数)。这样连只多了 \(n\times(2+\log n)\) 条边,大概是最优的连法。

然后对 \(s\neq 1\) 的情况跑一遍 dijkstra 就做完了,是目前最优解。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 2e5 + 5, M = 5e5;
int n, m, s, k;
int hh[N], to[N << 4], ne[N << 4], cnt;
ll dis[N], w[N << 4];
bool yz[N];
struct rmm
{
	ll dis; int u;
	bool operator < (const rmm &a) const {return a.dis < dis;}
};
namespace W
{
    void Wadd(int u, int v, ll val)
    {
        to[++cnt] = v;
        w[cnt] = val;
        ne[cnt] = hh[u];
        hh[u] = cnt;
    }
    void Wdij(int x)
    {
        priority_queue<rmm> q;
        memset(dis, 0x3f, sizeof dis);
        dis[x] = 0;
        q.push({0, x});
        while(q.size())
        {
            int u = q.top().u; q.pop();
            if(yz[u]) continue;
            yz[u] = 1;
            for(int i = hh[u]; i != -1; i = ne[i])
            {
                int v = to[i];
                if(dis[v] > dis[u] + w[i])
                {
                    dis[v] = dis[u] + w[i];
                    q.push({dis[v], v});
                }
            }
        }
    }
}
namespace W1
{
    short main()
    {
        fill(dis + 1, dis + 1 + n, 0);
        int zc = 1;
        while(zc <= n) zc *= 2;
        if(n == zc - 1)
        {
            dis[n] = k;
            for(int i = hh[n]; i != -1; i = ne[i])
                dis[n] = min(dis[n], w[i]);
        }
        else dis[n] = 0;
        fo(i, 2, n) printf("%lld ", dis[i]); puts("");
        return Ratio;
    }
}
namespace W2
{
    short main()
    {
        fo(i, 0, n) fo(j, 0, 16)
        {
            int v = i ^ (1 << j);
            ll val = 1ll * k * (1 << j);
            if(v <= n) W::Wadd(i, v, val);
        }
        W::Wdij(1);
        fo(i, 2, n) printf("%lld ", dis[i]); puts("");
        return Ratio;
    }
}
namespace W3
{
    short main()
    {
        fo(i, 0, n) 
        {
            fo(j, 0, 16)
            {
                int v = i ^ (1 << j);
                if(v <= n)
                {
                    ll val = ((i >> j) & 1) ? 0 : 1ll * k * (1 << j);
                    W::Wadd(i + n + 1, v + n + 1, val);
                }
            }
            W::Wadd(i, i + n + 1, 1ll * k * i);
            W::Wadd(i + n + 1, i, 0);
        }
        W::Wdij(1);
        fo(i, 2, n) printf("%lld ", dis[i]); puts("");
        return Ratio;
    }
}
namespace Wisadel
{
    short main()
    {
        freopen("jump.in", "r", stdin) , freopen("jump.out", "w", stdout);
        n = qr, m = qr, s = qr, k = qr;
        memset(hh, -1, sizeof hh);
        fo(i, 1, m)
        {
            int a = qr, b = qr, c = qr;
            W::Wadd(a, b, c), W::Wadd(b, a, c);
        }
        if(s == 1) return W1::main();
        if(s == 2) return W2::main();
        if(s == 3) return W3::main();
        return Ratio;
    }
}
signed main(){return Wisadel::main();}

D. 区间 (interval)

据说是线段树区间历史和板子。

又双叒叕回去整改了,打的不烂。只是 T3 好多性质没切,有点恼。

赛后一分钟得知 T1 建 110 条边就过了,大样例需要建 99 条,本地跑 0.95s 多,念在 OJ 速度不如本地,只建了 100 条。

下午信友队晚上 STAOI,所以现在才发。

Upd:这两场打的都还行。

尝试着跳过今天,使得 CSP 赶在我状态好的时候。

下午改 T4,改信友队题。


完结撒花~

现找的。

image

标签:ch,int,09,lx,qr,模拟,dis,NOIP2024,define
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18487005

相关文章

  • 「模拟赛」多校 A 层联训 8
    A.排列最小生成树(pmst)大家都没签上的签到调参调到110能过?!但赛时用set这个大常数选手存的边,挂了个log,所以跑不动大样例。正解:发现只按把编号相邻的点连边构成一条链,此时所有边的长度都\(\len\),所以无论如何我们都能保证最小生成树每条边的边权\(\len\)。那么我们......
  • 多校A层冲刺NOIP2024模拟赛09
    又双叒叕垫底啦rank4,T150,T2100,T339,T435。accoder上同分,rank20排列最小生成树(pmst)打的\(O(n^2\logn^2)\)暴力发现总是存在⼀颗⽣成树,使得⽣成树⾥的所有边的边权都⼩于\(n\)。考虑Kruskal的过程,我们只需要留下那些边权⼩于\(n\)的边。然后用桶排序即可。点......
  • json-server详细模拟GET、POST、DELETE等接口数据教程
    引言在前端开发过程中,我们经常需要在后端API尚未就绪的情况下模拟接口数据。json-server是一个强大而灵活的工具,可以帮助我们快速创建一个模拟的RESTfulAPI。本文将详细介绍如何使用json-server来模拟GET、POST、PUT、PATCH、DELETE等常用的HTTP方法,以及如何处理复杂的数......
  • csp-s 模拟 12
    csp-s模拟12T小h的几何whk我能说什么呢...T小w的代数仙人掌,DP,计数题本题部分分较有启发意义考虑是一棵树怎么做注意到\(n\)比较小,直接想想比较暴力的做法,可以用\(O(n^2)\)的复杂度枚举起点和终点,而由于是一棵树,两点之间的路径是唯一的,并且本题要求点集不重,......
  • 209号资源-源程序:(SIC)黑翼风筝算法:一种受自然启发的元启发式算法,用于解决基准函数和工
    ......
  • springboot叙州区图书馆管理系统设计与实现---附源码60921
    摘 要图书馆作为知识传播和学术研究的重要场所,扮演着非常关键的角色。随着信息技术的快速发展和图书馆管理的日益复杂化,传统的手工管理方式已经无法满足现代图书馆的需求。因此,采用计算机技术和信息系统来辅助图书馆管理成为一种必要的选择。本系统的前端界面涉及的技......
  • 使用application模拟聊天室
    <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>Session测试</title......
  • 多校A层冲刺NOIP2024模拟赛09
    GG多校A层冲刺NOIP2024模拟赛09T1排列最小生成树(pmst)需要思考一会。你得发现一个性质:所有要的边的权值都得小于n,因为每个点都可以找到至少一条边权小于n的边,所以最后生成树里的边的边权一定小于n。那么$\vertp_i-p_j\vert\times\verti-j\vert$中较......
  • 使用sendReddirect模拟用户登录
    <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>简单登录模拟</title>......
  • 09视图
    视图......