A组T1 锻造 (forging)

1.1 题目背景

勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打
于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现......自己连一个史莱姆都打不过了。
勇者的精灵路由器告诉勇者其实是他自己的武器不好,并把他指引到了锻造厂。

1.2题目描述

“欢迎啊,老朋友。”
一阵寒暄过后,厂长带他们参观了厂子四周,并给他们讲锻造的流程。
“我们这里的武器分成若干的等级,等级越高武器就越厉害,并且对每一等级的武器都有两种属性值 b 和 c,但是我们初始只能花 a 个金币来生产 1 把 0 级剑......”
“所以你们厂子怎么这么垃圾啊,不能一下子就造出来 999 级的武器吗?”勇者不耐烦的打断了厂长的话。
“别着急,还没开始讲锻造呢......那我们举例你手中有一把 x 级武器和一把 y 级武器 (y = max(x − 1, 0)),我们令锻造附加值 k = min(c x , b y ),则你有 k/cx 的概率将两把武器融合成一把 x + 1 级的武器。”
“......但是,锻造不是一帆风顺的,你同样有 1− k/cx 的概率将两把武器融合成一把 max(x − 1, 0) 级的武器......”
勇者听完后暗暗思忖,他知道厂长一定又想借此机会坑骗他的零花钱,于是求助这个村最聪明的智者——你,来告诉他,想要强化出一把 n 级的武器,其期望花费为多少?
由于勇者不精通高精度小数,所以你只需要将答案对 998244353(7 ×17 × 2 23 + 1,一个质数 ) 取模即可。

1.3 格式

1.3.1 输入格式

第一行两个整数 n, a,含义如题所示。
为了避免输入量过大,第二行五个整数 bx, by, cx, cy, p,按照下列代码
来生成 b 和 c 数组。

b[]=by+;c[]=cy+;
for(int i=;i<n;i++){
b[i]=((long long)b[i-]*bx+by)%p+;
c[i]=((long long)c[i-]*cx+cy)%p+;
}

1.3.2 输出格式

输出一行一个整数,表示期望花费。

1.4 样例

1.4.1 样例 1 输入

0 6432
4602677 3944535 2618884 6368297 9477531

1.4.2 样例 1 输出

6432

1.4.3 样例 2 输入

1 3639650
6136976 5520115 2835750 9072363 9302097

1.4.4 样例 2 输出

150643649

1.4.5 样例 3 输入

10 2
2 33 6 66 2333333

1.4.6 样例 3 输出

976750710

1.4.7 样例 4 输入

200 5708788
0 0 0 0 1

1.4.8 样例 4 输出

696441597

1.5数据范围

测试点 n<= 特殊性质
1 0 n/a
2 1 n/a
3 200
4 200 n/a
5 2000
6 2000 a/n
7 10^6
8 10^6 n/a
9 10^7
10 10^7 n/a

对于特殊性质处标示为“有”的数据满足 p = 1。
对于 100% 的数据,0 ≤ a ≤ 10^7 , 0 ≤ bx, by, cx, cy < p < 10^7 , 0 ≤ n ≤10^7

总算是自己想出来正解来的分析

考场上本来想打暴力,打着打着就把正解推出来了。。

直接设dp[i]表示获得i级武器需要的代价,用p来表示本次合成成功的概率。看起来dp[i]=(dp[i-1]+dp[i-2])/p。为什么是除以p呢?举个例子,如果在一个袋子里有无数多个球,黑色的占20%,那么平均拿几次才能拿到黑色的球呢?显然是1÷(20%)=5次。

但这个dp式子是错的,因为合成失败后还会剩下一把i-2级的武器可以用,而我们列出的转移式子并没有把它用上。既然失败后会获得i-2级的武器,那么i-2级的武器在合成中只需要一把即可,不需要去除p,所以dp式子应该是dp[i]=dp[i-1]/p+dp[i-2]。另外,这道题卡常。。。

官方总结:

代码:

#include<cstdio>
#include<algorithm>
#define mod 998244353
using namespace std;
int n,a,bx,by,cx,cy,p,dp[];
int b[],c[],inv[];
int main()
{
//freopen("forging.in","r",stdin);freopen("forging.out","w",stdout);
inv[]=;
scanf("%d%d%d%d%d%d%d",&n,&a,&bx,&by,&cx,&cy,&p);
for(int i=;i<=p+;i++)inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
b[]=by+;c[]=cy+;dp[]=a;
for(int i=;i<n;i++)
{
b[i]=((long long)b[i-]*bx+by)%p+;
c[i]=((long long)c[i-]*cx+cy)%p+;
dp[i]=(dp[max(i-,)]+1ll*dp[i-]*c[i-]%mod*inv[min(c[i-],b[max(i-,)])]%mod)%mod;
}
printf("%d\n",dp[n]=(dp[max(n-,)]+1ll*dp[n-]*c[n-]%mod*inv[min(c[n-],b[max(n-,)])]%mod)%mod);
}

A组T2 整除 (division)

2.1 题目描述

整除符号为 |,d|n 在计算机语言中可被描述为 n%d == 0。
现有一算式 n| xm−x,给定 n,m,求[1, n]以内 x 解的个数。
解可能很大,输出取模 998244353。

2.2 格式

2.2.1 输入格式

其中 n 的给定方式是由 c 个不超过 t 的质数的乘积给出的,c 和 t 的范围会在数据范围中给出。
第一行一个 id 表示这个数据点的标号。
多组数据,其中第二行一个整数 T 表示数据组数。
对于每一组数据:
第一行两个整数 c 和 m。
第二行 c 个整数,这些整数都是质数,且两两不同,他们的乘积即为n。
由于你可以通过输入求出 t,输入不再给出。

2.2.2 输出格式

对于每组数据输出一行,表示解的个数。

2.3 样例

2.3.1 样例输入

0
1
2 3
2 3

2.3.2 样例输出

6

根本没学过数论还是要在这里强行分析

网上说根据中国剩余定理,可知

整个方程组的解的个数便等于方程组中每个方程在(1~p)的解的个数的乘积。个人理解就是第一组方程的一个解乘上第二组方程的一个解便可获得一个解(不是很严谨)我们就可以遍历1到p来求得每个方程的解。但是m很大,就算是快速幂也会T。但是我们发现x^m可以由它的约数的m次方相乘得到,所以只需要将质数的m次方算出,再用类似线性筛的方法把其它合数的m次方算出来即可。这是原博客地址:https://blog.csdn.net/ShadyPi/article/details/83047995,还有一种更好的方法:https://www.cnblogs.com/ImagineC/p/9880891.html

这仍然是一道卡常的好题

来自官方的总结

代码:

#include<cstdio>
int T,c,m,ans,f[],p[],vis[];
int qp(int a,int k,int mod)
{
int res=;
while(k)
{
if(k&)res=res*a%mod;
k/=;a=a*a%mod;
}
return res;
}
int sieve(int n)
{
int cnt=;p[]=;
for(int i=;i<n;cnt+=(f[i]==i),i++)
{
if(!vis[i])p[++p[]]=i,f[i]=qp(i,m,n);
for(int j=;j<=p[];j++){if(i*p[j]>n)break;vis[i*p[j]]=;f[i*p[j]]=f[i]*f[p[j]]%n;if(i%p[j]==)break;}
}
return cnt;
}
int main()
{
//freopen("division.in","r",stdin);freopen("division.out","w",stdout);
for(scanf("%*d%d",&T);T--;)
{
scanf("%d%d",&c,&m);ans=;
for(int i=,a;i<=c;i++)scanf("%d",&a),ans=1ll*ans*sieve(a)%;
printf("%d\n",ans);
}
}

A组T3 欠钱 (money)

3.1 题目描述

南极的企鹅王国大学中生活着 n 只企鹅,作为 21 世纪的优秀大学生,企鹅们积极响应“大众创业,万众创新”的号召,纷纷创业。但是创业需要资金,企鹅们最近手头比较紧,只能互相借钱。
企鹅的借钱行为是有规律可循的:每只企鹅只会借一次钱,并且只会从一只企鹅那里借钱。借钱关系中不存在环(即不存在类似“金企鹅欠银企鹅钱,银企鹅欠铜企鹅钱,铜企鹅欠金企鹅钱”这种情况)。
企鹅的还钱行为也是有规律可循的:每只企鹅一旦新获得了一笔钱,就会立刻用这笔钱尽可能偿还自己欠的债务,直到债务偿清或用光这笔钱。它只会使用新获得的这笔钱,至于以前它有没有钱、有多少钱,与还钱行为无关。
企鹅们经常会做美梦。在一只企鹅 A 的梦里,它梦见自己创业成功,一下子获得了 +∞ 元钱,于是(按照上文的还钱规则)它赶快把钱用来还债,接着拿到钱的那只企鹅也赶快把钱用来还债......如此往复,直到所有获得钱的企鹅都完成了还债操作。梦醒之后,它开心地把梦的内容告诉了另外一只企鹅 B,企鹅 B 听了,也很开心,于是它问道:在你的梦里,我获得了多少钱呢?(指 B 去还债之前手里的钱,包括后来用于还债的钱和还债后B 手里剩下的钱。)
梦毕竟是梦,对实际的欠债情况没有影响。

3.2格式

3.2.1输入格式

第一行两个整数 n 和 m,表示有 n 只企鹅,m 个操作。
接下来 m 行,有两种可能的格式:

  • 0 a b c:修改操作,企鹅 a 向企鹅 b 借了 c 元钱。
  • 1 a b:查询操作,询问假如 a 有了 +∞ 元钱,企鹅 b 会净收入多少钱。

本题强制在线,也就是说:对于每个操作输入的变量 a, b, c(如果没有c,那就只有 a, b)都不是实际的 a, b, c,想获得实际的 a, b, c 应当经过以下操作:
a = (a + lastans) % n + 1;
b = (b + lastans) % n + 1;
c = (c + lastans) % n + 1;
其中,lastans 是上一次询问的答案。如果没有上一次询问,lastans 为0。

3.2.2输出格式

对每个询问操作,输出一行一个数表示答案。

3.3样例

3.3.1样例输入

5 9
0 1 2 1
0 0 1 2
1 0 1
1 2 4
0 2 1 1
1 2 0
0 3 1 0
1 4 2
1 3 4

3.3.2样例输出

3
2
0
1
0

3.4 数据范围

数据分为以下几种:
第一种:占 10%,n ≤ 5000 且 m ≤ 10000;
第二种:占 20%,所有借钱事件(0 开头的操作)发生在所有询问事件(1 开头的操作)之前;
第三种:占 30%,对于一只企鹅 A,最多只有一只企鹅向 A 借钱;
第四种:占 40%,没有特殊性质,n、m 大小有一定梯度。
对于所有数据,满足:n ≤ 10^5 ,m ≤ 10^6 ,0 ≤ a, b, c ≤ n 且 a != b。

分析

LCT裸题???可是我不会打。只需要维护链上最小值,连根都不用换。至于如何判断b能否到达a?先access(b),打通b到根的路径,此时lca(a,b)一定与b在同一个splay里面。再access(a),打通根到a的路径,记录最后一次打通的点,画图可知,它一定是a和b的lca。b能到达a则一定有lca(a,b)=b,判断即可。

仍然是一道卡常的题。

疯狂压行后还开O3的代码:

#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls ch[x][0]
#define rs ch[x][1]
#define get(x) (ch[fa[x]][0]==x||ch[fa[x]][1]==x?ch[fa[x]][1]==x:-1)
using namespace std;
const int maxn=2e6+;
int n,m,a,b,c,ans,ord,mn[maxn],val[maxn];
int tot,ch[maxn][],fa[maxn];
inline void pushup(register int x){mn[x]=min(val[x],min(mn[ls],mn[rs]));}
int read(){register int x=,f=;char ch;while(ch<''||ch>'') {if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return f*x;}
void print(int x){if(x>)print(x/);putchar(x%+'');}
void rotate(register int x)
{
register int f=fa[x],ff=fa[f],flag=get(x);
if(get(f)!=-)ch[ff][get(f)]=x;
fa[x]=ff;fa[f]=x;if(ch[x][!flag])fa[ch[x][!flag]]=f;
ch[f][flag]=ch[x][!flag];ch[x][!flag]=f;pushup(f);
}
void splay(int x)
{
for(register int y=fa[x];get(x)!=-;rotate(x),y=fa[x])
if(get(y)!=-)rotate(get(x)==get(y)?y:x);
pushup(x);
}
inline int access(register int x){register int f=;for(;x;x=fa[f=x])splay(x),rs=f,pushup(x);return f;}
inline void link(register int x,register int y){splay(x);fa[x]=y;}
int main()
{
//freopen("money.in","r",stdin);freopen("money.out","w",stdout);
     scanf("%d%d",&n,&m);memset(mn,,sizeof mn);memset(val,,sizeof val);tot=n;
while(m--)
{
ord=read();a=(read()+ans)%n+;b=(read()+ans)%n+;
if(ord)access(b),(access(a)==b?print(ans=min(val[b],mn[ch[b][]])):print(ans=)),puts("");
else c=(read()+ans)%n+,val[++tot]=c,mn[tot]=c,link(a,tot),link(tot,b);
}
}

中山纪中集训Day4双是测试(划沝) 九校联考-DL24凉心模拟Day2的更多相关文章

  1. 中山纪中集训Day5叒是测试(划淼)

    A组T1 矩阵游戏(game) 九校联考24OI__D1T1 问题描述 LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个N行M列的矩阵.第一行的数字是1,2,…M,第二行的数字是M+1,M+2…2*M ...

  2. 「中山纪中集训省选组D1T1」最大收益 贪心

    题目描述 给出\(N\)件单位时间任务,对于第\(i\)件任务,如果要完成该任务,需要占用\([S_i, T_i]\)间的某个时刻,且完成后会有\(V_i\)的收益.求最大收益. 澄清:一个时刻只能做 ...

  3. 中山纪中集训Day2又是测试(划水)

    A组T1 bzoj 2674 Attack Description chnlich 非常喜欢玩三国志这款游戏,并喜欢用一些策略出奇制胜.现在,他要开始征服世界的旅途了.他的敌人有N 座城市和N 个太守 ...

  4. 中山纪中集训Day1测试(摸鱼)

    AT3 粉刷匠 Description 赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= = 现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍.赫克托有K桶颜色各不 ...

  5. 「中山纪中集训省选组D4T1」折射伤害 高斯消元

    题目描述 在一个游戏中有n个英雄,初始时每个英雄受到数值为ai的伤害,每个英雄都有一个技能"折射",即减少自己受到的伤害,并将这部分伤害分摊给其他人.对于每个折射关系,我们用数对\ ...

  6. 「中山纪中集训省选组D2T1」书堆 欧拉常数

    题目描述 蚂蚁是勤劳的动物,他们喜欢挑战极限.现在他们迎来了一个难题!蚂蚁居住在图书馆里,图书馆里有大量的书籍.书是形状大小质量都一样的矩形.蚂蚁要把这些书摆在水平桌子的边缘.蚂蚁喜欢整洁的布置,所以 ...

  7. 洛谷 P4363 [九省联考2018]一双木棋chess 解题报告

    P4363 [九省联考2018]一双木棋chess 题目描述 菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落 ...

  8. 【BZOJ5248】【九省联考2018】一双木棋(搜索,哈希)

    [BZOJ5248][九省联考2018]一双木棋(搜索,哈希) 题面 BZOJ Description 菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手.棋局开始时,棋盘上没有任何 ...

  9. 纪中集训 Day 2

    今天(其实是昨天= =)早上起来发现好冷好冷啊= = 吃完饭就准备比赛了,好吧B组难度的题总有一道不知到怎么写QAQ 太弱了啊!!! 蒟蒻没人权啊QAQ 今天第4题不会写,在这里说说吧 题目的意思就是 ...

随机推荐

  1. [React] 函数定义组件

    函数定义组件的例子 function Welcome(props) { return <h1>Hello, {props.name}</h1>; } 该函数是一个有效的 Rea ...

  2. UI5-技术篇-签字板

    签字板应用是通过创建自定义控件实现的,相关代码如下: 1.HTML <!DOCTYPE HTML> <html> <head> <meta http-equi ...

  3. org.springframework.dao.DuplicateKeyException: 问题

    转自:https://blog.51cto.com/chengxuyuan/1786938 org.springframework.dao.DuplicateKeyException: a diffe ...

  4. 关于SqlServer数据库数据备份失败的问题

    当备份的失败,出现说什么应该支持多少个介质簇,但实际出现了多少介质簇,这个时候就要考虑备份的地址是不是出现问题. 首先,检查备份地址,是不是多于两个以上,那么在备份的时候应该注意,备份地址最好留一个, ...

  5. mybatis中如何将多个表的查询结果,放入结果集中返回

    1.首先需要将resultMap进行改造,为了避免对其他sql的影响建议另外定义一个resultMapExtral,避免id相同, 2.然后在resultMapExtral中添加其它表的字段,若多个表 ...

  6. 2013.4.26 - KDD第八天

    下午上Android课,我看中秋也选这个课了,然后在上半节的时候速补了一下秦海龙师兄的那篇文章.中间休息的时候窜到了中秋那里,然后讨论了半节课现在的情况. 现在的情况是这样的: 中 秋开始是没有进行主 ...

  7. java写入内容到本地文件 -读取文件内容

    /** 日志记录 * @author sys * @param content 要写入的类容 * @param path 目标路径 c:/log/ * @param filename 文件名 log. ...

  8. Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [VCodeModel]

    2019-08-20 17:53:24,054 [ERROR] [http-nio-8047-exec-1] [HttpResult.java : 143] 系统异常 org.springframew ...

  9. python 杂记20191102

    上下文管理器: def __exit__(self, exc_type, exc_val, exc_tb):若exc_tb不是空,则说明有异常返回值只能是true或false,若是false,则会把之 ...

  10. 第122题:买卖股票的最佳时机II

    一. 问题描述 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交 ...