『模拟赛』多校A层冲刺NOIP2024模拟赛12
Rank
挂了不少,还行
Upd:加了张 p
A. Alice 和璀璨花
签。
一眼最长上升子序列,昨天在 AT 专题里刚见过,不过赛时没想到离散化之后树状数组,所以打的动态开点,结果细节挂了 30pts。
和最长上升子序列思路基本一致,直接区间查询
常数略大,稍微卡卡就过去了。几个卡常 trick:动态开点加取地址符会快很多;没事把函数都加上 inline
;剪枝尽量;快读 + printf
+ puts
;空间开够;不要 #define int long long
!
点击查看代码
// ubsan: undefined
// accoders
#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)--)
typedef long long ll;
using namespace std;
#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 pll pair<ll, ll>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 1e6 + 5;
int n, b[N], f[N], ans, cnt = 1;
ll a[N], maxx, MA;
int t[N * 20], son[N * 20][2];
namespace Wisadel
{
#define ls son[rt][0]
#define rs son[rt][1]
#define mid ((l + r) >> 1)
inline void Wpushup(int rt)
{
t[rt] = max(t[ls], t[rs]);
}
inline void Wadd(int &rt, ll l, ll r, ll x, int k)
{
if(!rt)rt=++cnt;
if(l == r){t[rt] = max(t[rt], k); return ;}// !
if(x <= mid)
{
Wadd(ls, l, mid, x, k);
}
else
{
Wadd(rs, mid + 1, r, x, k);
}
Wpushup(rt);
}
inline int Wq(int rt, ll l, ll r, ll x, ll y)
{
if(!rt) return 0;
if(x <= l && r <= y) return t[rt];
int ans = 0;
if(x <= mid) ans = Wq(ls, l, mid, x, y);
if(y > mid) ans = max(ans, Wq(rs, mid + 1, r, x, y));
return ans;
}
short main()
{
freopen("alice.in", "r", stdin), freopen("alice.out", "w", stdout);
n = qr;
fo(i, 1, n) a[i] = qr, MA = max(MA, a[i]);
fo(i, 1, n) b[i] = qr, maxx = max(maxx, MA * b[i]);
int rot = 1;
fo(i, 1, n)
{
f[i] = Wq(1, 1, maxx, 1, a[i] - 1) + 1;
Wadd(rot, 1, maxx, 1ll * a[i] * b[f[i]], f[i]);
ans = max(ans, f[i]);
}
printf("%d\n", ans);
return Ratio;
}
}
signed main(){return Wisadel::main();}
B. Bob 与幸运日
解同余方程 + 分讨,挺 ex 的。
暴力直接跑,不过要注意
正解仙姑,估计需要复习板子。 板子是复习不下去的,不如改改。
其实只要稍微化一下式子然后分讨就完了。
考虑原式:
上下相加相减得到:
把两式子中的
以上面的式子举例,当
再考虑只有一个等式的情况。此时一个
一组解只会在区间
点击查看代码
#pragma GCC optimize(3)
#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)--)
typedef long long ll;
using namespace std;
#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 pll pair<ll, ll>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 1e6 + 5;
ll m, d, w, a, b;
namespace Wisadel
{
inline ll Wqp(ll x, ll y)
{
ll res = 1;
x %= w;
while(y)
{
if(y & 1) res = res * x % w;
x = x * x % w;
y >>= 1;
}
return res;
}
inline bool Wno()
{
if((d - 1) % w == 0 && (a - b) % w != 0) return 0;
if((d + 1) % w == 0 && (a + b + 2 * d) % w != 0) return 0;
return 1;
}
short main()
{
freopen("bob.in", "r", stdin), freopen("bob.out", "w", stdout);
int T = qr;
while(T--)
{
m = qr, d = qr, w = qr, a = qr, b = qr;
if(!Wno()){puts("0"); continue;}
ll len = min(m, d);
ll xady = (a + b + 2 * d) % w * Wqp(d + 1, w - 2) % w;
ll yrex = (b - a + w) % w * Wqp((d - 1 + w) % w, w - 2) % w;
ll y = (xady + yrex) % w * Wqp(2, w - 2) % w, x = (xady - yrex + w) % w * Wqp(2, w - 2) % w;
if(((d - 1) % w == 0 && (b - a) % w == 0) || ((d + 1) % w == 0 && (a + b + 2 * d) % w == 0))
{
ll zc = len % w, z1 = (len - 1) / w + 1, z2 = z1 - 1;
if(!zc)
{
printf("%lld\n", z1 * len);
continue;
}
ll l, r;
if((d - 1) % w == 0 && (b - a) % w == 0) r = (xady - 1 + w) % w, l = (xady - zc + w) % w;
else r = (len - yrex + w) % w, l = (1 - yrex + w) % w;
ll tim = len / w, d1 = tim * (r >= l ? r - l + 1 : r - l + w), d2 = len;
len %= w;
if(l <= r)
{
zc = min(len, r) - max(1ll, l) + 1;
if(l > len) zc = 0;
d1 += zc;
}
else
{
d1 += min(len, r) + max(len, l) - l + 1;
if(len < l) d1--;
}
d2 -= d1;
printf("%lld\n", d1 * z1 + d2 * z2);
continue;
}
if(!y) y = w;
if(!x) x = w;
ll a1 = 0, a2 = 0;
if(len >= y) a1 = 1 + (len - y) / w;
if(len >= x) a2 = 1 + (len - x) / w;
printf("%lld\n", a1 * a2);
}
return Ratio;
}
}
signed main(){return Wisadel::main();}
C. Charlie 的运输网
有点复杂的树上问题。
暴力就是每次
正解仙姑。
D. David 与和谐号
迭代加深搜索。
首先一个上界
点击查看代码(41ms)
#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)--)
typedef long long ll;
using namespace std;
#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 pll pair<ll, ll>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 30 + 5;
int n, ans;
int a[N];
namespace Wisadel
{
inline int Wq()
{
int res = 0;
fo(i, 1, n) res += (abs(a[i] - a[i + 1]) != 1);
return res;
}
inline bool Wdo(int res)
{
int zc = Wq();
if(res + zc > ans) return 0;
if(res == ans) return !zc;
fo(i, 2, n)
{
reverse(a + 1, a + 1 + i);
if(Wdo(res + 1)) return 1;
reverse(a + 1, a + 1 + i);
}
return 0;
}
short main()
{
freopen("david.in", "r", stdin), freopen("david.out", "w", stdout);
int T = qr;
while(T--)
{
n = qr, ans = 0;
fo(i, 1, n) a[i] = qr;
a[n + 1] = n + 1;
while(!Wdo(0)) ans++;
printf("%d\n", ans);
}
return Ratio;
}
}
signed main(){return Wisadel::main();}
末
CSP 前最后一场模拟赛,紧张是肯定的,有些地方明显失常了。
T1 想剪枝想假了,发现赛时的做法会漏掉某个区间内的值,其实还是没手动算最坏的时空复杂度,每次最多加
考前心态最重要,没准这挂的 40pts 就在之后的某次更重要的比赛上复活了。
加油,我的第一次,也是最后一次。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探