2022.10.16———HZOI【CSP-S模拟19】游寄
排名
得分
总结:
场切题我写了个shab贪心搞了
本来想小 一把,然后发现 假了
考场思路是对的,但是不知道脑子哪里抽了就给否了。然后想到 在超大定义域里随机撒点撒到 就来气,所以直接开始大力撒点。因为有 所以最后只有 。
刚开始看到 的部分分挺开心,后来意识到这玩意的求方案数没那么简单。
T1:木棍,T2:环,T3:传令,T4:序列
思路跟别人不大一样。但是感觉是个假做法。
赛时的思路是 一共有五种分法,2+2+2+2+2
、2+2+2+4
、2+4+4
、3+3+2+2
、3+3+4
,仔细思考了一下发现两个三个 能合成一个 ,两个 也能合成一个 , 和 也能合成一个 ,于是就把 拆成了 。发现似乎是个方程,所以设了一下完全由 变成 的个数为 和由 与 变成 的个数为 。
设 为 的个数,那么首先就是让 全部转化为 (你留着他也没啥别的用啊)。
因为要尽量让 和 相等,那么有:
移项整理得:
发现 即为新增的 的个数,正好是我们想要的,所以直接解出来赋值给 。因为方程满足了 ( 或者 多一个少一个可以忽略,因为你多一个 或者多一个 你又不能自己凑出来答案),所以此时 就是能凑出来的 的个数。
发现这样做第三个样例是过不去的,于是怀着爆零的心态加了个nb特判,结果就 了。。。
具体加的特判就是如果 极大的话就直接让 和 去全部合成 ,统计答案输出。 极大指的就是 全部和 去转换为 后, 还是比 大,即 。
T1
/*
做总结
T1 贪心+分类讨论?
T2 找简单环。我 超
T3 没想出来啥 有点像树的重心
T4 魔鬼时空限制 还有看不出来是啥题 应该是个dp+组合数 以及样例似乎走丢了(
开题顺序:T1 -> T2 -> T3 -> T4
还有 T2 T4 要开文件
*/
#include <cstdio>
#include <cctype>
#include <iostream>
#define GMY (520&1314)
#define char_phi int
#define re register int
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout)
#define Endl cout << '\n'
#define _ ' '
#define Dl cerr << '\n'
#define DMARK cerr << "###"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define ll __int128
using namespace std;
// inline void Fastio_setup(){ ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL); }
/*
考虑10的分法
10 = 2+2+2+2+2
= 2+2+2+4
= 2+4+4
= 3+3+4
= 3+3+2+2
于是就大力分类讨论?
数据组数只有100是什么鬼啊(
之前似乎在哪做过类似的题
发现了神奇的东西
可以把4给全部转成2
哦吼
但是会炸long long
所以开 __int128 反正noip也让用
于是便只剩两种情况了
wow!!!
然后再把n3给全部整成6
那么剩下的就比较显然了,首先满足n3,再满足五个n2就行了
c,假了
我说出题人怎么会闲的没事考__int128
但是经过一番思考我决定特判
又想到了神奇的玩应。。。
把2和3都转成6
首先当然是把3全部转成6
由于2+2 -> 4,2+4 -> 6
所以考虑让6和4尽可能地等同需要分讨一下
又假,wc
我囸,两个小时了,我赶紧开别的题去
唉希望别爆零
*/
inline ll read(){
ll x = 0; char c;
while (!isdigit(c = getchar()));
do { x = (x << 3) + (x << 1) + (c & 15); } while (isdigit(c = getchar()));
return x;
}
void ot(ll x){
if (x > 9) ot(x/10);
putchar((x%10)+48);
}
ll T, n2, n3, n4, final_ans, n6;
inline void work(){
final_ans = 0;
n2 = read(), n3 = read(), n4 = read();
n6 = n3/2;
if (n6 >= n4+n2/2){// n6已经够多了
final_ans = (n4+n2/2);
}
else {// n6还少,需要转化
// 然后考虑用2+4去转化还是用2+2+2去转化
// 小解一把方程
// 发现不用exgcd都
if (n4-n2 > n6+n2)// 如果n4极大
{ n6 = n6 + n2; final_ans = n6; goto OUT; }
// cout << "res: "; ot((2*n4 - 2*n6 + n2) / 5), putchar('\n');
ll res = (2*n4 - 2*n6 + n2) / 5;// x+y
n6 = n6 + res;
// res < 0 说明n6多,不可能,因为确定了 n6*2 < n4*2 + n2 了
// 那么6的个数就是n6个啦。
final_ans = n6;
}
OUT:{}
ot(final_ans); putchar('\n');
}
#undef int
// #define IXINGMY
char_phi main(){
#ifdef IXINGMY
FBI_OPENTHEDOOR(a, a);
#endif
// Fastio_setup();
T = read();
while (T --)
work();
return GMY;
}
贺的陈嘉然先生的。
T2
#include <iostream>
#include <algorithm>
#define GMY (520&1314)
#define char_phi signed
#define re register int
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define Endl cout << '\n'
#define _ ' '
#define Dl cerr << '\n'
#define DMARK cerr << "###"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 5005
#define P 998244353
#define mod %
using namespace std;
inline void Fastio_setup(){ ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL); }
/*
*/
long long n, final_ans;
long long a[N], f[N];
inline long long ksm(long long A, long long B){
long long res(1);
while (B != 0){
if ((B & 1) == 1) res = res * A mod P;
A = A * A mod P;
B >>= 1;
}
return res;
}
inline void work(){
cin >> n;
for (re i = 1 ; i <= n ; ++ i)
cin >> a[i];
sort(a+1, a+n+1);
f[0] = 1;
for (re i = 1 ; i <= n ; ++ i){
for (re j = a[i-1]+1 ; j <= a[i] ; ++ j)
for (re k = j ; k >= 1 ; -- k)
f[k] = (f[k] + f[k-1]) mod P;
final_ans = (final_ans + (f[1]-a[i]+P) mod P) mod P;
for (long long j = 0 ; j <= a[i] ; ++ j)
f[j] = (f[j] + f[j+1] * (j+1) mod P * j mod P) mod P;
}
cout << final_ans * ksm(2, P-2) mod P << '\n';;
}
// #define IXINGMY
char_phi main(){
#ifdef IXINGMY
FBI_OPENTHEDOOR(a, a);
#endif
Fastio_setup();
work();
return GMY;
}
:
稍微改一下就过了。。。最后一道题似乎不是只改一下,于是我就懒得做了(
对此 的评价如下:
// T3
// 弱化版 P3942 将军令
// 弱化弱化版 P2279 [HNOI2003]消防局的设立
// 弱的不是很化的改编版 P2016 战略游戏(准确的说这个是大胖守皇宫的弱化?)
// 加的不是很强的一样版 P3523 [POI2011] DYN-Dynamite
// 你谷全是重题, jbl
这回不是贺的了。从下午的两点多开始改(自己的nt思路),一直到晚上的七点,我tm改了一个下午。。。
先说思路。首先你二分答案一个时间。递归到叶子后往根回溯,然后贪心地选择当前点是否要作为国王选择的城市。
思路十分明确且简单,然后就是代码实现了。
然后代码实现我走了错路。(或者说我太弱了根本没调出来)
被覆盖指的是在某一作为国王选择的城市的点的影响范围内(就是你二分的时间内,距离就是影响范围)
我用结构体形式返回两个变量,分别是从当前点往下第一个没能被覆盖的点的深度(当然有可能因为贪心跑到他的上边,不过没关系),第二个是当前点往下第一个作为国王选择的城市的深度。然后就大力分类讨论,调了无数个数据点,最后忍痛放弃换了 的代码实现方式。
的实现方式特别简洁。当然我猜他的码风会让他的代码变得不是很简洁,不过我没看他代码。
设当前二分的值为 tmpans
。
整一个 a[]
数组,先考虑链上的情况。具体地:
-
叶子节点的
a[]
为0。 -
一个父亲的
a[]
值为其儿子a[]
值 (如果其儿子a[]
值 后 )。 -
当一个点的
a[]
值 时,将他的a[]
值变为 。
这么做的原因显然,是为了贪心嘛。当前点除了能往上覆盖 长度之外,贪心地在他上面的 处建立新的点。这样直接覆盖了更多的距离。自己画一条链就理解了。
但是毕竟链是链,不是树。考虑树的情况下应该咋合并。
假设一个节点 ,他的儿子传过来的 a[]
值中,最大值和最小值分别为 和 。首先a[x]肯定是要儿子于是做以下分类讨论:
-
如果 并且 ,也就是说 的儿子把 给覆盖过了,那么根据贪心原则显然不会再选 。
-
如果 ,也就是说 的儿子中覆盖了 的儿子不仅能把 给覆盖,还能覆盖掉 其他的儿子。那么此时就算 也不会将 选上。
-
其他情况下 的
a[]
值应为 。原因也显然,为了让 的父亲知道最深的在哪。
还有最后根节点需要特判一下。因为你是是贪心地选 的,有可能根节点正好处于 之间,你贪心的时候不会把根节点选上,但是你不选根节点你那一块就直接没被覆盖了。所以特判一下是否要选根节点。
代码实现较为简单。按照我那一版写的话代码实现较为恶心。
T3
#include <iostream>
#include <algorithm>
#define GMY (520&1314)
#define char_phi signed
#define re register int
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define Endl cout << '\n'
#define _ ' '
#define Dl cerr << '\n'
#define DMARK cerr << "###"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 5005
#define P 998244353
#define mod %
using namespace std;
inline void Fastio_setup(){ ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL); }
/*
*/
long long n, final_ans;
long long a[N], f[N];
inline long long ksm(long long A, long long B){
long long res(1);
while (B != 0){
if ((B & 1) == 1) res = res * A mod P;
A = A * A mod P;
B >>= 1;
}
return res;
}
inline void work(){
cin >> n;
for (re i = 1 ; i <= n ; ++ i)
cin >> a[i];
sort(a+1, a+n+1);
f[0] = 1;
for (re i = 1 ; i <= n ; ++ i){
for (re j = a[i-1]+1 ; j <= a[i] ; ++ j)
for (re k = j ; k >= 1 ; -- k)
f[k] = (f[k] + f[k-1]) mod P;
final_ans = (final_ans + (f[1]-a[i]+P) mod P) mod P;
for (long long j = 0 ; j <= a[i] ; ++ j)
f[j] = (f[j] + f[j+1] * (j+1) mod P * j mod P) mod P;
}
cout << final_ans * ksm(2, P-2) mod P << '\n';;
}
// #define IXINGMY
char_phi main(){
#ifdef IXINGMY
FBI_OPENTHEDOOR(a, a);
#endif
Fastio_setup();
work();
return GMY;
}
作为纪念我还是挂一下我写的屎山代码。
屎山代码
#include <iostream>
#include <cstring>
#define GMY (520&1314)
#define char_phi signed
#define re register int
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define Endl cout << '\n'
#define _ ' '
#define Dl cerr << '\n'
#define DMARK cerr << "###"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 200005
using namespace std;
inline void Fastio_setup(){ ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL); }
// #define Debug
/*
T3好简单好像
我赛时想麻烦了
我刚发现
我赛时的想法似乎是正确的
二分一个答案
然后直接跑树形dp
是O(nlogn)?
*/
/*
17 2
17 7
10 14
6 5
16 17
17 4
11 9
4 10
10 11
16 8
1 2
14 6
4 13
17 12
5 3
3 1
17 15
*/
/*
9 3
8 3
6 4
5 7
5 9
5 8
6 1
7 6
9 2
*/
/*
22 2
9 16
12 19
5 2
7 14
14 18
8 3
17 22
5 13
19 20
9 6
19 15
22 7
13 9
4 1
4 5
22 10
15 11
20 21
21 4
16 8
17 12
*/
/*
18 3
12 18
11 13
12 17
5 9
10 5
4 8
17 14
3 11
17 15
10 4
8 3
7 1
18 2
5 16
12 10
8 7
11 6
*/
/*
17 3
7 2
8 16
11 5
14 9
8 12
4 17
15 11
10 8
2 3
11 7
4 10
1 14
7 1
10 15
12 13
11 6
*/
int n, K, star_cnt, final_ans, chscnt, tmpans;
char chs[N];
int head[N], dep[N];
struct star {int v, nxt;};
struct RTN {int mxdep, mnchs;};
struct star e[N<<1];
struct RTN U_L_S;
inline void star_add(int u, int v){ e[++ star_cnt].v=v, e[star_cnt].nxt=head[u], head[u]=star_cnt; }
inline int Max(int x, int y){ return MAX(x, y); }
inline int Min(int x, int y){ return MIN(x, y); }
void getdep(int x, int faer){
for (re i = head[x] ; i ; i = e[i].nxt){
int v = e[i].v;
if (v == faer)
continue;
dep[v] = dep[x]+1;
getdep(v, x);
}
}
RTN dfs(int x, int faer){
int mxdep(-1145141919), mnchs(1145141919);
for (re i = head[x] ; i ; i = e[i].nxt){
int v = e[i].v;
if (v == faer)
continue;
/*long long deper;
deper = dfs(v, x);
#ifdef Debug
cerr << "感谢来自 " << v << " 老板的 " << deper << '\n';
#endif*/
RTN tmp = dfs(v, x);
mxdep = Max(mxdep, tmp.mxdep);
mnchs = Min(mnchs, tmp.mnchs);
}
#ifdef Debug
cerr << "dfs: " << x << _ << dep[x] << _ << mxdep << _ << mnchs << '\n';
Dl;
#endif
if (x == 1 and (mnchs-tmpans-1 >= dep[x] or mxdep-tmpans-1 >= dep[x]))
{ chs[x] = true; return (RTN){1, 1}; }
if (mxdep == -1145141919 and mnchs == 1145141919)// 啥都没干,是个叶子
{ /*cerr << x << "[1]" << '\n'; Dl; Dl;*/ return (RTN){dep[x], mnchs}; }
else if (mxdep-dep[x] >= tmpans and mnchs-dep[x]+mxdep-dep[x] > tmpans)// 该选
{ /*cerr << x << "[2]" << '\n'; Dl; Dl;*/ chs[x] = true; return (RTN){dep[x]-tmpans-1, dep[x]}; }
else if (mnchs-dep[x]+mxdep-dep[x] <= tmpans)// 当前点的mxdep被其他子树控制了,不用选,直接返回
{ /*cerr << x << "[3]" << '\n'; Dl; Dl;*/ return (RTN){mnchs-tmpans-1, mnchs}; }
else // 最最最普通的链
{ /*cerr << x << "[4]" << '\n'; Dl; Dl;*/ return (RTN){mxdep, mnchs}; }
/*if (mxdep == -1145141919)// 啥都没干,是个叶子
{ cerr << x << "返回了[1]" << dep[x] << '\n'; return dep[x]; }
if (mxdep-dep[x] >= tmpans)// 此处应当有chs
{ cerr << x << "返回了[2]" << dep[x]-tmpans-1 << '\n'; chs[x] = true; return dep[x]-tmpans-1; }
else // 不够格(
{ cerr << x << "返回了[3] " << mxdep << '\n'; return mxdep; }*/
}
inline char check(int mid){// 那应当是check写挂了
memset(chs, false, sizeof(chs)); chscnt = 0;
#ifdef Debug
cerr << "~~~~~~~~~~~~~mid: " << mid << '\n';
#endif
tmpans = mid;
U_L_S = dfs(1, 0);
for (re i = 1 ; i <= n ; ++ i)
if (chs[i] == true)
chscnt ++;
#ifdef Debug
cerr << "chscnt: " << chscnt << '\n';
cerr << "选了:";
for (re i = 1 ; i <= n ; ++ i)
if (chs[i] == true)
cerr << i << _;
Dl;
#endif
if (chscnt <= K)
return true;
else
return false;
}
inline void work(){
cin >> n >> K;
for (re i = 1, uu, vv ; i <= n-1 ; ++ i)
{ cin >> uu >> vv; star_add(uu, vv), star_add(vv, uu); }
dep[1] = 1;
getdep(1, 0);
/*for (re i = 1 ; i <= n ; ++ i)
if (check(i) == true)
{final_ans = i; break;}*/
#ifdef Debug
Dl; Dl; Dl;
#endif
int l, r, mid;
l = 1, r = n;
while (l <= r){
mid = (l+r) >> 1;
if (check(mid) == true)// 时限可以更小
final_ans = mid, r = mid-1;
else
l = mid+1;
#ifdef Debug
Dl; Dl; Dl;
#endif
}
cout << final_ans << '\n';
}
// #define IXINGMY
char_phi main(){
#ifdef IXINGMY
FBI_OPENTHEDOOR(a, a);
#endif
Fastio_setup();
work();
return GMY;
}
没改(
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现