T1 锻造 forging

题目描述

“欢迎啊,老朋友。”

一阵寒暄过后,厂长带他们参观了厂子四周,并给他们讲锻造的流程。

“我们这里的武器分成若干的等级,等级越高武器就越厉害,并且对每一等级的武器都有两种属性值 b 和 c,但是我们初始只能花\(a\)个金币来生产\(1\)把\(0\)级剑......”

“所以你们厂子怎么这么垃圾啊,不能一下子就造出来\(999\)级的武器吗?”勇者不耐烦的打断了厂长的话。

“别着急,还没开始讲锻造呢......那我们举例你手中有一把\(x\)级武器和一把\(y\)级武器\((y = max(x − 1, 0))\),我们令锻造附加值\(k = min(c_x , b_y )\),则你有 \(\frac{k}{c_x}\) 的概率将两把武器融合成一把\(x + 1\)级的武器。”

“......但是,锻造不是一帆风顺的,你同样有 \(1−\frac{k}{c_x}\) 的概率将两把武器融合成一把\(max(x − 1, 0)\) 级的武器......”

勇者听完后暗暗思忖,他知道厂长一定又想借此机会坑骗他的零花钱,于是求助这个村最聪明的智者——你,来告诉他,想要强化出一把\(n\)级的武器,其期望花费为多少?

由于勇者不精通高精度小数,所以你只需要将答案对\(998244353\)取模即可。

分析

期望DP+线性逆元。

设\(f[i]\)表示打造成等级为\(i\)的武器的期望花费,那么考虑转移:

\[f[i]=f[i-1]+f[i-2]+P\times (f[i] - f[i - 2])
\]

其中,\(P=(1-\frac{k}{c_{i-1}})\),为打造失败的概率。

这个方程表示,若打造成功,那么花费即为\(f[i-1]+f[i-2]\),若未成功,那么我们就有了一件等级为\(i-2\)的武器,所以格外的花费就应该是\(f[i]-f[i-2]\),然后整理可得:

\[f[i]=\frac{c_{i-1}}{k} \times f[i-1]+f[i-2]
\]

然后再加个线性求逆元就行了。

时间复杂度\(O(n)\)。

#include<cstdio>
#include<cstdlib>
#define ll long long
#define Re register
const int N = 1e7 + 5;
const int P = 998244353;
inline int read() {
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
}
inline int min(int a, int b) { return a < b ? a : b; }
inline void hand_in() {
freopen("forging.in", "r", stdin);
freopen("forging.out", "w", stdout);
}
int n, a, bx, by, cx, cy, p, b[N], c[N], inv[N], f[N];
int main() {
hand_in();
inv[0] = inv[1] = 1;
for (Re int i = 2;i <= 10000000; ++i) {
inv[i] = (ll)(P - (P / i)) * (ll)inv[P % i] % P;
}
n = read(), a = read(), bx = read(), by = read(), cx = read(), cy = read(), p = read();
b[0] = by + 1, c[0] = cy + 1;
for (Re int i = 1;i < n; ++i) {
b[i] = ((ll)b[i - 1] * bx + by) % p + 1;
c[i] = ((ll)c[i - 1] * cx + cy) % p + 1;
}
f[0] = a, f[1] = ((ll)(((ll)c[0] * inv[min(c[0], b[0])]) % P + 1) * f[0]) % P;
for (int i = 2;i <= n; ++i) {
f[i] =((((ll)c[i - 1] * inv[min(c[i - 1], b[i - 2])]) % P * f[i - 1]) % P + f[i - 2]) % P;
}
printf("%d\n", f[n]);
return 0;
}

T2 整除 division

题目大意

求解\(x^m\equiv x (mod p_1\times p_2\times \dots \times p_c)\)在\([1, p_1\times p_2\times \dots \times p_c]\)区间取值间的个数。

分析

懒得写了,这里很清楚

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define Re register
const int N = 1e5 + 5;
const int P = 998244353;
inline int read() {
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
} inline int min(int a, int b) { return a < b ? a : b; } inline int max(int a, int b) { return a < b ? b : a; } inline void swap(int &a, int &b) { a ^= b ^= a ^= b; } inline void hand_in() {
freopen("division.in", "r", stdin);
freopen("division.out", "w", stdout);
} inline ll mi(ll a, ll b, ll p) {
ll ret = 1;
while (b) {
if (b & 1) ret *= a, ret %= p;
a *= a, a %= p;
b >>= 1;
}
return ret;
} int prim[N], vis[N], tot;
inline void Prim() {
vis[1] = 1;
for (int i = 2;i <= 10000; ++i) {
if (!vis[i]) prim[++tot] = i;
for (int j = 1;j <= tot; ++j) {
if (prim[j] * i > 10000) break;
vis[prim[j] * i] = 1;
if (!(i % prim[j])) break;
}
}
} int pw[N]; inline int calc(int m, int p) {
pw[1] = 1, pw[p] = 0;
for (int i = 2;i < p; ++i) {
if (!vis[i]) pw[i] = mi(i, m, p);
for (int j = 1;prim[j] <= i; ++j) {
if (prim[j] * i > p) break;
pw[prim[j] * i] = pw[prim[j]] * pw[i];
if (!(i % prim[j])) break;
}
}
int ret = 1;
for (int i = 1;i < p; ++i) ret += (pw[i] == i);
return ret;
} inline ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b);
} int id, T, c, m, ans; int main() {
hand_in();
id = read();
T = read();
Prim();
while (T --) {
c = read(), m = read();
ans = 1;
for (int i = 1, p;i <= c; ++i) {
p = read();
// ans = ((ll)ans * calc(m, p)) % P;
ans = ((ll)ans * (gcd(m - 1, p - 1) + 1)) % P;
}
printf("%d\n", ans);
}
return 0;
}

T3 欠钱 money

分析

将有向有根树改成无向无根树存下来,树上倍增+启发式合并,每次合并时暴力重构倍增数组,倍增数组多存一个到\(2^i\)的父节点的方向,全向上为\(1\),全向下为\(2\),两个都有为\(3\),询问时判断两个点的方向关系就可以了。

时间复杂度\(O(nlog^2n + mlogn)\)。

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define Re register
const int N = 1e5 + 5;
const int INF = 0x7fffffff;
const int BASE = 16;
inline int read() {
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
} inline void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
} inline int min(int a, int b) { return a < b ? a : b; } inline void swap(int &a, int &b) { a ^= b ^= a ^= b; } inline void hand_in() {
freopen("money.in", "r", stdin);
freopen("money.out", "w", stdout);
} int n, m, last; struct Graph {
int to[N << 1], nxt[N << 1], w[N << 1], dir[N << 1], head[N], cnt;
inline void add(int x, int y, int z, int d) {
++cnt;
to[cnt] = y, w[cnt] = z, dir[cnt] = d, nxt[cnt] = head[x], head[x] = cnt;
}
}G; int f[N], sz[N];
int anc[N][BASE + 1], mn[N][BASE + 1], dir[N][BASE + 1], dep[N], up[N];
inline void init() {for (Re int i = 1;i <= n; ++i) f[i] = i, sz[i] = 1, up[i] = 1; } inline void dfs(int u, int fa, int rt) {
f[u] = rt, dep[u] = dep[fa] + 1;
for (Re int i = 1;i <= BASE; ++i) {
anc[u][i] = anc[anc[u][i - 1]][i - 1];
mn[u][i] = min(mn[u][i - 1], mn[anc[u][i - 1]][i - 1]);
dir[u][i] = (dir[u][i - 1] | dir[anc[u][i - 1]][i - 1]);
}
for (Re int i = G.head[u], v;i;i = G.nxt[i]) {
v = G.to[i];
if (v == fa) continue;
anc[v][0] = u;
mn[v][0] = G.w[i];
dir[v][0] = 3 ^ G.dir[i];
dfs(v, u, rt);
}
} inline void merge(int u, int v, int w) {
G.add(u, v, w, 1), G.add(v, u, w, 2);
int dirs = sz[f[u]] < sz[f[v]] ? 1 : 2;
if (dirs == 2) swap(u, v);
anc[u][0] = v, mn[u][0] = w, dir[u][0] = dirs;
sz[f[v]] += sz[f[u]];
dfs(u, v, f[v]);
} inline int ask(int u, int v) {
if (f[u] != f[v]) return 0;
int dirs = 0, res = INF;
if (dep[u] < dep[v]) swap(u, v), dirs = 3;
for (int i = BASE; i >= 0; --i) {
if (dep[u] - (1 << i) >= dep[v]) {
if (dir[u][i] != (1 ^ dirs)) return 0;
res = min(res, mn[u][i]);
u = anc[u][i];
}
}
if (u == v) return res;
for (int i = BASE;i >= 0; --i) {
if (anc[u][i] != anc[v][i]) {
if (dir[u][i] != (1 ^ dirs) || dir[v][i] != (2 ^ dirs)) return 0;
res = min(res, min(mn[u][i], mn[v][i]));
u = anc[u][i], v = anc[v][i];
}
}
if (dir[u][0] != (1 ^ dirs) || dir[v][0] != (2 ^ dirs)) return 0;
res = min(res, min(mn[u][0], mn[v][0]));
return res;
} int main() {
hand_in();
n = read(), m = read(), init();
for (Re int i = 1, op, a, b, c;i <= m; ++i) {
op = read(), a = read(), b = read();
a = (a + last) % n + 1;
b = (b + last) % n + 1;
if (!op) {
c = read();
c = (c + last) % n + 1;
merge(a, b, c);
}
else {
write(last = ask(a, b));
puts("");
}
}
return 0;
}

九校联考-DL24凉心模拟Day2总结的更多相关文章

  1. 中山纪中集训Day4双是测试(划沝) 九校联考-DL24凉心模拟Day2

    A组T1 锻造 (forging) 1.1 题目背景 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现......自己连一个史莱姆 ...

  2. 【九校联考-24凉心模拟】锻造(forging)

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

  3. 九校联考_24OI——餐馆restaurant

    凉心模拟D1T1--最简单的一道题 TAT 餐馆(restaurant) 题目背景 铜企鹅是企鹅餐馆的老板,他正在计划如何使得自己本年度收益增加. 题目描述 共有n 种食材,一份食材i 需要花ti 小 ...

  4. 九校联考 终&启

    one term's ending... class:12 school:130...130...130... 至今没有看到九校的排名,如果九校排名正常的话,那yyhs的学生也太可怕了...估计要三百 ...

  5. 九校联考(DL24凉心模拟) 整除(中国剩余定理+原根性质)

    题意简述 给定 \(n, m\),求 \(n|x^m - x\) 在满足 \(x \in [1, n]\) 时合法的 \(x\) 的数量.答案模 \(998244353\).单个测试点包含多组数据. ...

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

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

  7. 三校联考 Day3

    三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...

  8. [九省联考2018]秘密袭击coat

    [九省联考2018]秘密袭击coat 研究半天题解啊... 全网几乎唯一的官方做法的题解:链接 别的都是暴力.... 要是n=3333暴力就完了. 一.问题转化 每个联通块第k大的数,直观统计的话,会 ...

  9. 【BZOJ5250】[九省联考2018]秘密袭击(动态规划)

    [BZOJ5250][九省联考2018]秘密袭击(动态规划) 题面 BZOJ 洛谷 给定一棵树,求其所有联通块的权值第\(k\)大的和. 题解 整个\(O(nk(n-k))\)的暴力剪剪枝就给过了.. ...

随机推荐

  1. 一起学Makefile(四)

    变量的定义 makefile中的变量,与C语言中的宏类似,它为一个文本字符串(变量的值,其类型只能是字符串类型)提供了一个名字(变量名). 变量的基本格式: 变量名   赋值符   变量值 变量名指的 ...

  2. GoCN每日新闻(2019-11-09)

    GoCN每日新闻(2019-11-09) 1. Go语言发行10周年庆祝 https://blog.golang.org/10years2. 容器中某Go服务GC停顿经常超过100ms排查 https ...

  3. eclipse Target runtime com.genuitec.runtime.generic.jee50 is not defined

      1.情景展示 报错信息如下: 2.原因分析 使用eclipse导入myeclipse时,唯独这个报错信息改不了. 需要通过修改这个项目的配置文件才行. 3.解决方案 第一步:切换到导航视图: 第二 ...

  4. BigDecimal代码示例

    在平常开发中,如果涉及到计算,要求准确的精度,比如单价*数量=总价之类的计算,那么得用到BigDecimal. 初始化 如下: BigDecimal amount=new BigDecimal(&qu ...

  5. 【Beta】Scrum Meeting 8

    前言 Beta阶段第8次会议在5月13日22:00由PM在大运村一公寓三层召开, 时长30min. 任务分配 姓名 今日任务 明日任务 困难 周博闻 修复修改密码问题#54 添加主页公告栏 #57实现 ...

  6. 【Beta】Phylab 发布说明

    Phylab Beta阶段发布说明 一.发布地址 Phylab 二.新功能 1. Markdown(Html)报告生成 在生成报告界面可以选择报告生成方式:Latex或Markdown模板.目前支持M ...

  7. MyBatis(十一):Mybatis 动态SQL语句完成多条件查询

    之前文章中对in的用法做过讲解:<MyBatis(四):mybatis中使用in查询时的注意事项> 实际上对于多个参数的用法也是这是注意的: 多参&if判空&List集合判 ...

  8. 从太空到地球某个位置的轨迹录像制作 | Earth Zoom in/out Tutorial (Record Video)

    视频教程:Google Earth - Earth Zoom in/out Tutorial (Record Video) 下载google earth 在search里输入你想要去的地名 zoom ...

  9. Refused to execute script from '...' because its MIME type ('') is not executable, and strict MIME type checking is enabled.

    写在前面 部署项目到weblogic上启动首页访问空白, 浏览器控制台报如题错误. web.xml中把响应头添加防止攻击的报文过滤器禁用就行了(仅仅是为了启动), 以下为转载内容, 可以根据需要自行测 ...

  10. Spark无法读取hive 3.x的表数据

    通过Ambari2.7.3安装HDP3.1.0成功之后,通过spark sql去查询hive表的数据发现竟然无法查询 HDP3.0 集成了hive 3.0和 spark 2.3,然而spark却读取不 ...