test20190816 NOIP2019 模拟赛
100+100+20=220,T3吐槽:整个考室没有一个人正确地理解了题意。
树上路径(phantasm)
Akari 的学校的校门前生长着一排 n 棵树,从西向东依次编号为 1 ∼ n。相邻两棵树间的距离 都是 1。
Akari 上课的教学楼恰好在树 1 旁,所以每个课间,Akari 都很想走出教室,上树活动。Akari会依次经过 m 棵树,从树 1 一路向东跳到树 n。临近上课时,Akari 会再次上树,经过 m 棵树从树n 一路向西跳到树 1 ,准备上课。由于 Akari 睡眠很充足,Akari 每次跳跃至少会移动 k 的距离, 因此 Akari 在上树前需要合理规划她的跳跃路线。我们称每次上树过程中 Akari 跳过的全部 m 棵 树(包含树 1 和树 n)的集合为一条树上路径。
Akari 喜欢按不同的顺序观察各种树木,因此她每次上树时选择的树上路径不会与之前选择过 的重复。这意味着,Akari 不会选择之前的课间选过的树上路径,且在从树 n 跳回树 1 时,也不会 沿这次跳到树 n 的树上路径原路返回。
如果一次课间开始时,Akari 找不到符合条件的树上路径,那么她从此会放弃上树活动,开始 专心学习。如果一次课间即将即将结束时,Akari 还在树 n 且找不到符合条件的树上路径回到树 1, 她就会十分沮丧,选择逃课。
请你帮助 Akari 判断,她是否会在某个课间选择逃课。
【输入格式】
从文件 phantasm.in 中读入数据。 每个测试点可能包含多组数据。第一行一个正整数 T ,表示数据组数。 每组数据包括一行三个正整数 n, m, k,含义见题目描述。
【输出格式】
输出到文件 phantasm.out 中。
对于每组数据,输出一行一个字符串。如果 Akari 会逃课,输出 Yes ,否则输出 No 。
请. 注. 意. 输. 出. 字. 符. 串. 的. 大. 小. 写. 。
【样例 1 输入】
3
10 3 2
5 3 1
15 5 3
【样例 1 输出】
No Yes No
【样例 1 解释】
第一组数据中,除了起点和终点外,合法的树上路径只能经过 3, 4, 5, 6, 7, 8 这 6 棵树,所以合 法的树上路径只有 6 种,经过 3 个课间后 Akari 就会停止上树活动。
第二组数据中,合法的树上路径有 3 种,Akari 会在第 2 个课间结束时逃课。 第三组数据中,合法的树上路径有 10 种。
【样例 2 输入】
4
15 | 4 | 3 |
---|---|---|
15 | 4 | 4 |
15 | 5 | 3 |
16 | 3 | 7 |
【样例 2 输出】
Yes No No No
【样例 3】
见选手目录下的 phantasm/phantasm3.in 与 phantasm/phantasm3.ans。
【子任务】
测试点 | n | m | k | T |
---|---|---|---|---|
1 | ≤ 10 | ≤ 10 | ≤ 10 | ≤ 10 |
2 | ≤ 16 | ≤ 16 | ≤ 16 | ≤ 102 |
3 | ||||
4 | ≤ 18 | ≤ 18 | ≤ 18 | |
5 | ||||
6 | ||||
7 | ≤ 5, 000 | ≤ 5, 000 | ≤ 1 | ≤ 5, 000 |
8 | ≤ 3 | ≤ 5, 000 | ||
9 | ≤ 5, 000 | ≤ 2 | ||
10 | ≤ 200 | ≤ 200 | ≤ 200 | ≤ 200 |
11 | ||||
12 | ≤ 5, 000 | |||
13 | ||||
14 | ≤ 5, 000 | ≤ 5, 000 | ≤ 5, 000 | |
15 | ||||
16 | ≤ 2 × 106 | |||
17 | ||||
18 | ||||
19 | ≤ 109 | ≤ 109 | ≤ 109 | |
20 |
对于所有数据,2 ≤ n, m ≤ 109 , 1 ≤ k ≤ 109 , 0 ≤ T ≤ 2 × 106 ,保证第一个课间 Akari 从树 1 跳到
树 n 的符合条件的树上路径存在。
【提示】
本题的输入数据可能很大,请避免使用过于缓慢的读入方式。
题解
首先把那个点数化成长度,然后不同的长度拆分就是不同的方案。
那么答案就是有下界的拆分,直接套公式(或者像我一样手动构造)即可。
\]
使用卢卡斯定理即可。时间复杂度\(O(T \log v)\)。
bool binom(LL n,LL m){
if(n<m) return 0;
if(m==0) return 1;
return (n&1)>=(m&1) && binom(n>>1,m>>1);
}
int main(){
freopen("phantasm.in","r",stdin),freopen("phantasm.out","w",stdout);
for(int T=read<int>();T--;){
LL n=read<LL>(),m=read<LL>(),k=read<LL>();
puts(binom(n-1-(k-1)*(m-1)-1,m-1-1)?"Yes":"No");
}
return 0;
}
利用二进制的优良性质,可以将单次操作化为\(O(1)\)的,参见std
int ks = io;
while (ks--) {
int n = io, m = io, k = io;
io << ((((n - 2 - (m - 1) * (k - 1)) & (m - 2)) == m - 2) ? "Yes\n" : "No\n");
}
话说回来,我好像不会证明卢卡斯定理,放一个图
非常的有道理啊。
另外既然我都看到\((1+x)^p \equiv x^p + 1 \mod p\),那我就说一下今天讨论出来的多项式快速幂做法。
若保证\(f_0=1\),则\(f^k(x)=f^{k\mod p}(x)\mod x^n\)。
证明大概就是有组合数的项因为卢卡斯定理变成\(0\)了,而剩下的是\(x^{kp},k=1\sim n-1\)和\(1\)。但是我们要对\(x^n\)取模,所以那些有\(x\)的项都被消掉了。所以\(f^p(x)=1 \mod x^n\)。
泳池(skylines)
【题目描述】
小 A 的城市里有 n 座工厂,编号分别为 1 ∼ n。工厂间连有 n − 1 条双. 向. 管道,形成一个无向连. 通. 图,其中每条管道都有一定的长度,连接在两座不同的工厂间。
每座工厂都装有废水处理设施,工厂 i 的蓄水量记为 ci 。由于工厂规模有限,工厂产生的废水必须经由管道输送到另. 一座工厂进行处理。
工厂 u 将废水输送到工厂 v 处理时,所需的运. 输. 成. 本. 等于无向图中 u, v 间最短路径的长度,并且会产生 cu − cv 的额. 外. 成. 本. (可能为负)。总成本等于运输成本与额外成本的和。
为了降低污染,在接下来的 q 天内,每一天只有一座工厂会产生废水。你需要确定这座工厂将废水输送到哪一座工厂进行处理,可使得总成本最小。由于选择可能不唯一,你只需输出最小的总 成本。
【输入格式】
从文件 skylines.in 中读入数据。 第一行一个正整数 n。
第二行 n 个正整数 ci 。
下接 n − 1 行,每行三个正整数 u, v, w,表示一条双向管道两端工厂的编号及长度。 第 n + 2 行一个正整数 q。
下接 q 行,每行一个正整数 x,表示这一天进行生产的工厂的编号。
【输出格式】
输出到文件 skylines.out 中。
输出 q 行,每行一个整数,表示这一天总成本的最小值。
【样例 1 输入】
5
7 | 7 | 6 9 9 |
---|---|---|
2 | 5 | 5 |
2 | 3 | 1 |
4 | 1 | 1 |
1 | 2 | 2 |
4
2
5
3
4
【样例 1 输出】
1
7
0
3
【样例 1 解释】
第 1 天,工厂 2 输送到工厂 4 是一种最优方案,成本为 3 + (−2) = 1。
第 2 天,工厂 5 输送到工厂 2 是一种最优方案,成本为 5 + 2 = 7。
第 3 天,工厂 3 输送到工厂 2 是一种最优方案,成本为 1 + (−1) = 0。
第 4 天,工厂 4 输送到工厂 1 是一种最优方案,成本为 1 + 2 = 3。
【样例 2】
见选手目录下的 skylines/skylines2.in 与 skylines/skylines2.ans。
【样例 3】
见选手目录下的 skylines/skylines3.in 与 skylines/skylines3.ans。
【样例 4】
见选手目录下的 skylines/skylines4.in 与 skylines/skylines4.ans。
【子任务】
测试点 | n, q | 链 |
---|---|---|
1 | ≤ 10 | 否 |
2 | ≤ 200 | |
3 | ≤ 2, 000 | 是 |
4 | ||
5 | 否 | |
6 | ||
7 | ≤ 2 × 105 | 是 |
8 | ||
9 | 否 | |
10 |
对于表格中“链”为“是”的数据,保证所有管道满足 v = u + 1 且以 u 递增的顺序输入。
对于所有数据,2 ≤ n ≤ 2 × 105 , 1 ≤ q ≤ 2 × 105 , 1 ≤ u, v, x ≤ n, 1 ≤ w ≤ 5000, 1 ≤ ci ≤ 108 。
题解
显然这是一道离线的问题。
开始像“情报中心”那样推式子
=\min_{v \neq u} \{ dep_u+dep_v-2dep_{lca} + c_u -c_v \}
\]
确定一个根后,能作为\(u\)的\(lca\)的只可能是\(u\)的祖先,所以这就变成了统计子树内部\(dep_v-c_v\)的睿智题。注意支持换根需要记录最优次优解,或者像我一样记录儿子的值来搞序列问题。
时间复杂度\(O(n+q)\)。
co int N=200000+10;
co LL INF=1e18;
int n;LL c[N];
vector<int> to[N];vector<LL> we[N];
LL dep[N],g[N],f[N]; // g: x itself not included
vector<LL> son[N],pre[N],suf[N];
void dfs1(int x,int fa){
f[x]=dep[x]-c[x],g[x]=INF;
son[x].resize(to[x].size()); // edit 1: fa
for(rg int i=0;i<(int)to[x].size();++i){
int y=to[x][i],w=we[x][i];
if(y==fa){
son[x][i]=INF;
continue;
}
dep[y]=dep[x]+w;
dfs1(y,x);
g[x]=min(g[x],f[y]);
son[x][i]=f[y];
}
f[x]=min(f[x],g[x]);
pre[x].resize(son[x].size()),suf[x].resize(son[x].size());
for(rg int i=0;i<(int)son[x].size();++i){
pre[x][i]=son[x][i];
if(i>0) pre[x][i]=min(pre[x][i],pre[x][i-1]);
}
for(rg int i=(int)son[x].size()-1;i>=0;--i){
suf[x][i]=son[x][i];
if(i<(int)son[x].size()-1) suf[x][i]=min(suf[x][i],suf[x][i+1]);
}
}
LL ans[N];
void dfs2(int x,int fa,LL val){
ans[x]=dep[x]+c[x]+min(g[x]-2LL*dep[x],val);
for(rg int i=0;i<(int)to[x].size();++i){
int y=to[x][i];
if(y==fa) continue;
LL nval=dep[x]-c[x]-2LL*dep[x];
if(i>0) nval=min(nval,pre[x][i-1]-2LL*dep[x]);
if(i<(int)to[x].size()-1) nval=min(nval,suf[x][i+1]-2LL*dep[x]);
dfs2(y,x,min(val,nval));
}
}
int main(){
freopen("skylines.in","r",stdin),freopen("skylines.out","w",stdout);
read(n);
for(rg int i=1;i<=n;++i) read(c[i]);
for(rg int i=1;i<n;++i){
int u=read<int>(),v=read<int>();LL w=read<LL>();
to[u].push_back(v),we[u].push_back(w);
to[v].push_back(u),we[v].push_back(w);
}
dfs1(1,0);
dfs2(1,0,INF);
for(rg int q=read<int>();q--;) printf("%lld\n",ans[read<int>()]);
// cerr<<clock()<<endl;
return 0;
}
其他做法
刘老爷的点分治:还是那个式子,点分暴力做得了。时间复杂度\(O(n\log n+q)\)。
黄学长的换根+线段树:线段树可以支持相邻两个点换根。时间复杂度\(O(n\log n+q)\)。
空之轨迹(kiseki)
【题目描述】
Iri 近日沉迷游戏《英雄传说 VI 空之轨迹》。该游戏共有 n 个章节,第 i 章中有 ai 次战斗。当 第 i 章通关后,游戏会自动存档,然后自动进入第 i + 1 章,且不允许回到之前的章节(除非读档)。
由于 Iri 的游戏设备年久失修,这天早上 Iri 进入游戏时,发现他的所有存档都消失了,只留下初始的一个序章存档(加载后会开始第 1 章)。不幸的是,游戏的章节切换系统也出现了 Bug,在每一章结束的自动存档之后,游戏会从已有的所有存档(包括序章存档)中等概率随机选取一个加载。由于 Iri 的耐心与精力有限,加载序章存档后,他只会连续玩 m 个章节,然后更换新的设备。 需要注意的是,游戏的存档系统没有损坏,即当第 i 章结束后的自动存档被加载后,一定会开始第 i + 1 章。
现在 Iri 想知道,这 m 章内能进行的战斗总次数的期望值。Iri 觉得这个问题太简单了,所以就 把它交给了你。由于 Iri 的游戏技术同样出神入化,你可以认为所有章节他都会一次通关。
【输入格式】
从文件 kiseki.in 中读入数据。 第一行包含两个正整数 n, m. 第二行 n 个非负整数 ai .
【输出格式】
输出到文件 kiseki.out 中。
输出一行一个整数,表示 Iri 进行的战斗总次数的期望值在模 998244353 意义下的值。 即设答案化为最简分式后的形式为 \(\frac{a}{b}\) 其中 a 和 b 互质。输出整数 x 使得 bx ≡ a (mod 998244353) 且 0 ≤ x < 998244353。可以证明这样的整数 x 是唯一的。
【样例 1 输入】
3 2
1 2 1
【样例 1 输出】
499122179
【样例 1 解释】
答案是 \(\frac 52\) 。由于 499122179 × 2 mod 998244353 = 5,所以你输出 499122179。
【样例 2 输入】
3 3
5 5 1
【样例 2 输出】
332748132
【样例 3 输入】
15 10
2 8 6 3 2 6 3 5 9 2 3 4 5 1 6
【样例 3 输出】
653958763
【样例 4】
见选手目录下的 kiseki/kiseki4.in 与 kiseki/kiseki4.ans。
【子任务】
测试点 | n | m | 性质 1 |
---|---|---|---|
1 | ≤ 10 | ≤ 10 | 否 |
2 | |||
3 | ≤ 105 | ≤ 11 | |
4 | |||
5 | |||
6 | |||
7 | ≤ 21 | 是 | |
8 | |||
9 | |||
10 | |||
11 | ≤ 18 | 否 | |
12 | |||
13 | |||
14 | |||
15 | ≤ 21 | ||
16 | |||
17 | |||
18 | |||
19 | |||
20 |
对于具有性质 1 的数据,保证所有的 ai 都相等。
对于所有数据,保证 1 ≤ m ≤ 21, m ≤ n ≤ 105 , 0 ≤ ai ≤ 10.
【提示】
xp−1 ≡ 1 (mod p),其中 p 是质数,x 是 [1, p) 上的整数。
题解
首先说一下题意了。如果玩到之前玩过的关卡,那么会对下一个关卡又建一个存档,也就是说选到下一个关卡的概率会增大。看一下简化版的题意:
随机生成一个 m + 1 个数的数列,第一个数为 0, 生成第 i 个数时,在前 i − 1 个数中等概率选择一个数 k, 则第 i 个数为 k + 1。每个数均有一个对应的权值,求数列权值和的期望。
一个数列的权值和与数列中数的顺序无关,只与每种数的个数有关。
考虑 DP,状态中需要记录每种数的个数。可以发现,将得到的数列排序后,相邻两数的差只能为 \(0\) 或 \(1\)。
用二进制序列维护原数列的差分数组,即可表示数列中每种数的个数。
\(f(i, S)\) 表示生成了 \(i\) 个数,已有数列的差分为 \(S\) 的方案数。
\(S\)会如何变化呢?只能往\(S\)的末尾添\(1\),但是\(0\)可以随便加。所以\(S\)变化与它的加入位置有关。
则每种数列出现的概率 \(P(S) = \frac {f(m,S)}{m!}\)。
事先预处理出 \(tot_S\) 表示状态 \(S\) 所表示的数列的权值和, 最后的答案即为\(\sum_S P(S) tot_S\)。
复杂度:\(O(m · 2^m)\)。注意做除法时用乘法逆元计算。
说下状态的意思,状态的前两位是固定的01,表示序章存档和第一关存档,我们只需要记录后面的状态就行了。每次的转移的意思是跟简化版题意是一样。然后DP直接算概率,不是方案数。
#include<bits/stdc++.h>
#define co const
#define il inline
template<class T> T read(){
T x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x;
}
template<class T> il T read(T&x){
return x=read<T>();
}
using namespace std;
typedef long long LL;
co int mod=998244353;
il int add(int a,int b){
return (a+=b)>=mod?a-mod:a;
}
il int mul(int a,int b){
return (LL)a*b%mod;
}
co int N=30,S=1<<22;
int n,a[N],inv[N];
int f[S],g[S],c[N],p[N];
int main(){
freopen("kiseki.in","r",stdin),freopen("kiseki.out","w",stdout);
read<int>(),read(n);
for(int i=1;i<=n;++i) read(a[i]);
inv[0]=inv[1]=1;
for(int i=2;i<=n;++i) inv[i]=mul(mod-mod/i,inv[mod%i]);
f[0]=1,c[0]=1;
for(int i=2;i<=n;++i){
for(int s=0;s<1<<(i-2);++s){
int cur=1;
c[1]=1;
for(int j=0;j<i-2;++j){
if(s>>j&1) c[++cur]=1,p[cur]=j;
else ++c[cur];
}
for(int j=0;j<=cur;++j){
int t;
if(j==0) t=s<<1;
else if(j==cur) t=s|1<<(i-2);
else{
int h=s&((2<<p[j+1])-1);
t=(s^h)<<1|h;
}
g[t]=add(g[t],mul(c[j],mul(inv[i],f[s])));
}
f[s]=0;
}
swap(f,g);
}
int ans=0;
for(int s=0;s<1<<(n-1);++s){
int cur=1,sum=a[1];
for(int j=0;j<n-1;++j){
if(s>>j&1) ++cur;
sum+=a[cur];
}
ans=add(ans,mul(sum,f[s]));
}
printf("%d\n",ans);
return 0;
}
那个 n 的范围还有这个模数肯定是骗人去想多项式。
test20190816 NOIP2019 模拟赛的更多相关文章
- test20190827 NOIP2019 模拟赛
100+100+50=250.最后那道期望题需要用另外的方式统计. 精灵加护 ljss 被 M 个敌人打倒在地上啦!每个敌人有一个威力值 bi.但是他手中还拥有 N 把武器!每把武器有一个威力值 ai ...
- test20190826 NOIP2019 模拟赛
100+100+40=240.我觉得如果没做过第三题考场上却能想出来的都是神仙. 基因突变 [问题描述] 邪恶的 707 刚刚从白垩纪穿越回来,心中产生了一个念头:我要统治人类! 但是统治人类是很庞大 ...
- test20190818 NOIP2019 模拟赛
0+0+20=20,不给大样例,小数据又水,还没有题解的垃圾题. A 题 问题描述: long long ago, Lxhgww 统治的国家里有 n 个城市,其中某一个城市是 capital (首都) ...
- 题解 noip2019模拟赛Day1T3
题面 运河计划 问题描述 水运在人类的交通运输史中一直扮演着重要的角色.借助河流.的便利,人们得以把大量的货物输送到天南海北不仅仅是自然界现成的河流,人工开凿的运河(如苏伊士运河.巴拿马运河.我国的京 ...
- [NOIP2019模拟赛]LuoguP4261白金元首与克劳德斯
题目描述 给出坐标系中n个矩形,类型1的矩形每单位时间向x轴正方向移动1个单位,类型2的矩形向y轴正方向,初始矩形不重叠,一个点被矩形覆盖当且仅当它在矩形内部(不含边界),求$(-\infty ,+\ ...
- [NOIP2019模拟赛][AT2381] Nuske vs Phantom Thnook
题目链接 评测姬好快啊(港记号?)暴力40pts变成60pts 因为题目说了保证蓝色点两两之间只有一条路径,所以肯定组成了一棵树,而对于每次询问的x1,y1,x2,y2的子矩阵中就存在着一个森林 不难 ...
- [NOIP2019模拟赛]HC1147 时空阵
题目描述: 幽香这几天学习了魔法,准备建造一个大型的时空传送阵. 幽香现在可以在幻想乡的n个地点建造一些传送门,如果她建造了从地点a与地点b之间的传送门,那么从a到b和从b到a都只需要单位1的时间. ...
- [NOIP2019模拟赛]数数(gcd)
题目大意: 求l~r中有多少数与x互质,带单点修改 分析: 两个30的部分分很好打: ·n<=1000暴力O(nq)就好了 ·$a_i<=100$用树状数组维护每个x的前缀和就好了 100 ...
- [NOIP2019模拟赛]序列(Sequence)
题目大意 有一个序列$A_i$ • 对于 i ≥ 1,如果有$ A_i > 0.A_{i+1}> 0$ 且存在 $A_{i+2}$,那么法老可以令$ Ai$ 和 $A_{i+1}$ 减一, ...
随机推荐
- mycat实现读写分离
1 mysql已经配置好了主从 2 linux 安装java环境 3 linux 安装mycat cd /usr/local # 下载mycat wget http://dl.mycat.io/1.6 ...
- K8S从入门到放弃系列-(16)Kubernetes集群Prometheus-operator监控部署
Prometheus Operator不同于Prometheus,Prometheus Operator是 CoreOS 开源的一套用于管理在 Kubernetes 集群上的 Prometheus 控 ...
- Find the median(线段树+离散化)(2019牛客暑期多校训练营(第七场))
题目出处:Find the median 示例: 输入: 53 1 4 1 5 92 7 1 8 2 9 输出:3 4 5 4 5 说明:L = [3, 2 ,4, 1, 7],R = [4, 8, ...
- 启动Spring boot项目报错:java.lang.IllegalArgumentException: LoggerFactory is not a Logback
java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on t ...
- IdentityServer4实现OAuth2.0四种模式之授权码模式
接上一篇:IdentityServer4实现OAuth2.0四种模式之隐藏模式 授权码模式隐藏码模式最大不同是授权码模式不直接返回token,而是先返回一个授权码,然后再根据这个授权码去请求token ...
- power shell命令添加SharePoint用户组与用户(用户为域用户)
查看SharePoint用户组 Get-PnPGroup 查看某一用户组 Get-PnPGroup -Identity "用户组名" 查看某一用户组下的所有成员 Get-PnPGr ...
- 并发编程之Java锁
一.重入锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) .这些已经写好提供的锁为我们开发提 ...
- 【CF1095F】 Make It Connected(最小生成树)
题目链接 如果没有特殊边的话显然答案就是权值最小的点向其他所有点连边. 所以把特殊边和权值最小的点向其他点连的边丢一起跑最小生成树就行了. #include <cstdio> #inclu ...
- D1-JavaScript
下面的代码,我想要打印出hey jack,结果却打印出hey rose,为什么? function greet(person) { if (person == {name: 'jack'}) { co ...
- Qt ListWidget item 发起拖放
第一步:重写类 MyListWidget 继承自 QListWidget 第二步:重写 mousePressEvent 函数 和 mouseMoveEvent 函数 void mousePressEv ...