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.inphantasm/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 的符合条件的树上路径存在。

【提示】

本题的输入数据可能很大,请避免使用过于缓慢的读入方式。

题解

首先把那个点数化成长度,然后不同的长度拆分就是不同的方案。

那么答案就是有下界的拆分,直接套公式(或者像我一样手动构造)即可。

\[ans=\binom{(n-1)-(m-1)(k-1)-1}{(m-1)-1} \mod 2
\]

使用卢卡斯定理即可。时间复杂度\(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 间最短路径的长度,并且会产生 cucv. . . . (可能为负)。总成本等于运输成本与额外成本的和。

为了降低污染,在接下来的 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.inskylines/skylines2.ans

【样例 3】

见选手目录下的 skylines/skylines3.inskylines/skylines3.ans

【样例 4】

见选手目录下的 skylines/skylines4.inskylines/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, xn, 1 ≤ w ≤ 5000, 1 ≤ ci ≤ 108

题解

显然这是一道离线的问题。

开始像“情报中心”那样推式子

\[ans_u=\min_{v \neq u} \{ dist_{u,v} + c_u - c_v \}\\
=\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}\) 其中 ab 互质。输出整数 x 使得 bxa (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.inkiseki/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, mn ≤ 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 模拟赛的更多相关文章

  1. test20190827 NOIP2019 模拟赛

    100+100+50=250.最后那道期望题需要用另外的方式统计. 精灵加护 ljss 被 M 个敌人打倒在地上啦!每个敌人有一个威力值 bi.但是他手中还拥有 N 把武器!每把武器有一个威力值 ai ...

  2. test20190826 NOIP2019 模拟赛

    100+100+40=240.我觉得如果没做过第三题考场上却能想出来的都是神仙. 基因突变 [问题描述] 邪恶的 707 刚刚从白垩纪穿越回来,心中产生了一个念头:我要统治人类! 但是统治人类是很庞大 ...

  3. test20190818 NOIP2019 模拟赛

    0+0+20=20,不给大样例,小数据又水,还没有题解的垃圾题. A 题 问题描述: long long ago, Lxhgww 统治的国家里有 n 个城市,其中某一个城市是 capital (首都) ...

  4. 题解 noip2019模拟赛Day1T3

    题面 运河计划 问题描述 水运在人类的交通运输史中一直扮演着重要的角色.借助河流.的便利,人们得以把大量的货物输送到天南海北不仅仅是自然界现成的河流,人工开凿的运河(如苏伊士运河.巴拿马运河.我国的京 ...

  5. [NOIP2019模拟赛]LuoguP4261白金元首与克劳德斯

    题目描述 给出坐标系中n个矩形,类型1的矩形每单位时间向x轴正方向移动1个单位,类型2的矩形向y轴正方向,初始矩形不重叠,一个点被矩形覆盖当且仅当它在矩形内部(不含边界),求$(-\infty ,+\ ...

  6. [NOIP2019模拟赛][AT2381] Nuske vs Phantom Thnook

    题目链接 评测姬好快啊(港记号?)暴力40pts变成60pts 因为题目说了保证蓝色点两两之间只有一条路径,所以肯定组成了一棵树,而对于每次询问的x1,y1,x2,y2的子矩阵中就存在着一个森林 不难 ...

  7. [NOIP2019模拟赛]HC1147 时空阵

    题目描述: 幽香这几天学习了魔法,准备建造一个大型的时空传送阵. 幽香现在可以在幻想乡的n个地点建造一些传送门,如果她建造了从地点a与地点b之间的传送门,那么从a到b和从b到a都只需要单位1的时间. ...

  8. [NOIP2019模拟赛]数数(gcd)

    题目大意: 求l~r中有多少数与x互质,带单点修改 分析: 两个30的部分分很好打: ·n<=1000暴力O(nq)就好了 ·$a_i<=100$用树状数组维护每个x的前缀和就好了 100 ...

  9. [NOIP2019模拟赛]序列(Sequence)

    题目大意 有一个序列$A_i$ • 对于 i ≥ 1,如果有$ A_i > 0.A_{i+1}> 0$ 且存在 $A_{i+2}$,那么法老可以令$ Ai$ 和 $A_{i+1}$ 减一, ...

随机推荐

  1. jqGrid设置单选

    beforeSelectRow: function() { $(this).jqGrid('resetSelection'); return true; }

  2. mysql系统信息函数

    1.VERSION() 返回数据库的版本号 SELECT VERSION() -- 5.0.67-community-nt2.CONNECTION_ID() 返回服务器的连接数SELECT CONNE ...

  3. 自己实现简单版的注解Mybatis

    Mybatis属于ORM(Object Relational Mapping)框架,将java对象和关系型数据库建立映射关系,方便对数据库进行操作,其底层还是对jdbc的封装. 实现的思路是: 1 定 ...

  4. Response知识点小结

    HTTP协议: 1. 响应消息:服务器端发送给客户端的数据 * 数据格式: 1. 响应行 1. 组成:协议/版本 响应状态码 状态码描述 2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状 ...

  5. 二、SpringBoot基础配置

    目录 2.1 @SpringBootApplication 2.3 服务器配置 2.4 修改启动banner 小结 2.1 @SpringBootApplication 从上篇文章中知道@Spring ...

  6. websocket 函数

    函数名 描述 socket_accept() 接受一个Socket连接 socket_bind() 把socket绑定在一个IP地址和端口上 socket_clear_error() 清除socket ...

  7. Python解释器安装与环境变量添加

    Python解释器安装与环境变量添加 Python解释器安装(3.6和2.7): www.python.org这个是python解释器的官网,一定要牢记. 鉴于市场上有两种python版本(2和3), ...

  8. 如何解决visual studio2017 install 下载安装极慢的问题

    问题: visual studio 2017 下载安装速度慢,只有6.70kb/s.其他版本估计也有这个问题. 解决方案: 进入目录:C:\Windows\System32\drivers\etc 右 ...

  9. Select与Epoll的区别

      相同点: 都是IO多路转接,都是一个线程能同一时间等待一堆描述符 不同点: 1.select接口使用不方便,每次调用完select都需要重新设置fd_set,因为输入输出未分离,返回的fd_set ...

  10. xorm-创建时间created

    package main import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/ ...