A. 求和



求模s直接顺着递推。

求模2的次幂用倒推。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000105;
int n, m, K;
inline int qpow(int a, int b, int c) {int re = 1; a %= c;for(; b; b>>=1, a=1ll*a*a%c)if(b&1) re=1ll*re*a%c;return re;
}
int C[MAXN], F[MAXN];
void exgcd(int a, int b, int &x, int &y) {if(!b) { x = 1, y = 0; return; }exgcd(b, a%b, y, x); y -= x*(a/b);
}
int Inv(int N, int MOD) {int x, y; exgcd(N, MOD, x, y);x = (x % MOD + MOD) % MOD; return x;
}
int MOD, P;
struct node {int x, y;node(int x = 1, int y = 0):x(x), y(y){}inline node operator *(const node &o)const {return node(1ll*x*o.x%MOD, y+o.y);}
};
node get(int N) {node re;while(N % P == 0) N /= P, ++re.y;re.x = N; return re;
}
node inv(int N) {node re;while(N % P == 0) N /= P, --re.y;re.x = Inv(N, MOD); return re;
}
int cal(int p, int pk) {memset(C, 0, sizeof C);memset(F, 0, sizeof F);MOD = pk, P = p;int N = m+2; node now;for(int i = 1; i <= N && i <= n+2; ++i) {now = now * get(n+2-i+1) * inv(i);C[i] = 1ll * now.x * qpow(p, now.y, pk) % pk;}int inv2 = Inv(2, pk), re;re = F[0] = 1ll * C[1] * inv2 % pk;for(int i = 1; i <= m; ++i) {F[i] = 1ll * (C[i+1] - F[i-1]) % pk * inv2 % pk;if(!(i&1)) re = (re + F[i]) % pk;}return (re + pk) % pk;
}
int cnt, p[15], num[15], val[15];
int solve1(const int mod) { //sint tmp = mod;for(int i = 2; 1ll*i*i <= tmp; ++i)if(tmp % i == 0) {p[++cnt] = i; num[cnt] = 1;while(tmp % i == 0) tmp /= i, num[cnt] *= i;}if(tmp > 1) p[++cnt] = tmp, num[cnt] = tmp;int M = 1, re = 0;for(int i = 1; i <= cnt; ++i) val[i] = cal(p[i], num[i]), M *= num[i];for(int i = 1; i <= cnt; ++i) re = (re + 1ll * Inv(M/num[i], num[i]) * val[i] % mod * (M/num[i]) % mod) % mod;return re;
}
int solve2(int pk) {memset(C, 0, sizeof C);memset(F, 0, sizeof F);MOD = pk, P = 2;int N = m+2+30; node now;for(int i = 1; i <= N && i <= n+2; ++i) {now = now * get(n+2-i+1) * inv(i);C[i] = 1ll * now.x * qpow(2, now.y, pk) % pk;}F[m] = 0; int cf = 1;for(int i = m+2; cf; ++i) {F[m] = (F[m] + 1ll * cf * C[i]) % pk;cf = (-2ll) * cf % pk;}int re = F[m];for(int i = m-1; i >= 0; --i) {F[i] = (C[i+2] - 2ll*F[i+1]) % pk;if(!(i&1)) re = (re + F[i]) % pk;}return (re + pk) % pk;
}
int main () {scanf("%d%d%d", &n, &m, &K); if(n&1) --n; if(m&1) --m;int m1 = K, m2 = 1, t = 0;while(!(m1&1)) m1>>=1, m2<<=1, ++t;int v1 = solve1(m1), v2 = solve2(m2);int ans = (1ll*v1*Inv(m2, m1)*m2%K + 1ll*v2*Inv(m1, m2)*m1%K) % K;printf("%d\n", ans);
}

B.农民(farmer)


题解:对于一个权值为xxx的节点,它的左子树内的节点有可能被走到仅当其权值小于xxx,右子树内的节点有可能被走到仅当其权值大于xxx,那么树上每条边相当于给这条边以下的子树加了一个大于或是小于的限制,询问一个节点时,只要判断这个节点的权值是否同时满足到根路径上所有边的限制即可。我们可以用树链剖分加线段树维护这个限制,单点修改很好处理,子树翻转相当于取反子树内所有限制的符号,线段树同时维护一下翻转后的限制,打标记维护即可。时间复杂度O(n+mlog⁡2⁡n)O(n+m \log^2⁡n)O(n+mlog2⁡n)。

#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {char ch; int flg=1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); x*=flg;
}
const int MAXN = 100005;
const int inf = 1e9 + 5;
int n, m, rt, fa[MAXN], a[MAXN], ch[MAXN][2], top[MAXN], son[MAXN], sz[MAXN], dfn[MAXN], seq[MAXN], tmr;
void dfs1(int u) {sz[u] = 1;for(int i = 0, v; i < 2; ++i) if((v=ch[u][i])) dfs1(v), sz[u] += sz[v];son[u] = sz[ch[u][1]] > sz[ch[u][0]];
}
void dfs2(int u, int tp) {top[u] = tp; seq[dfn[u] = ++tmr] = u;if(ch[u][son[u]]) dfs2(ch[u][son[u]], tp);if(ch[u][son[u]^1]) dfs2(ch[u][son[u]^1], ch[u][son[u]^1]);
}
struct node {int a, b, c, d;node(int a=0, int b=inf, int c=0, int d=inf):a(a), b(b), c(c), d(d){}inline node rev() { return node(c, d, a, b); }inline node operator +(const node &o)const { return node(max(a, o.a), min(b, o.b), max(c, o.c), min(d, o.d)); }
}val[MAXN<<2]; bool rv[MAXN<<2];
void build(int i, int l, int r) {if(l == r) { val[i] = son[seq[l]] ? node(a[seq[l]], inf, 0, a[seq[l]]) : node(0, a[seq[l]], a[seq[l]], inf); return; }int mid = (l + r) >> 1;build(i<<1, l, mid);build(i<<1|1, mid+1, r);val[i] = val[i<<1] + val[i<<1|1];
}
inline void reving(int i) { val[i] = val[i].rev(); rv[i] ^= 1; }
inline void pd(int i) { if(rv[i]) rv[i]=0, reving(i<<1), reving(i<<1|1); }
void upd(int i, int l, int r, int x) {if(l == r) { val[i] = (son[seq[l]]^rv[i]) ? node(a[seq[l]], inf, 0, a[seq[l]]) : node(0, a[seq[l]], a[seq[l]], inf); return; }pd(i); int mid = (l + r) >> 1;x <= mid ? upd(i<<1, l, mid, x) : upd(i<<1|1, mid+1, r, x);val[i] = val[i<<1] + val[i<<1|1];
}
void mdf(int i, int l, int r, int x, int y) {if(x <= l && r <= y) { reving(i); return; }int mid = (l + r) >> 1; pd(i);if(x <= mid) mdf(i<<1, l, mid, x, y);if(y > mid) mdf(i<<1|1, mid+1, r, x, y);val[i] = val[i<<1] + val[i<<1|1];
}
node qry(int i, int l, int r, int x, int y) {if(x <= l && r <= y) return val[i];int mid = (l + r) >> 1; node re; pd(i);if(x <= mid) re = re + qry(i<<1, l, mid, x, y);if(y > mid) re = re + qry(i<<1|1, mid+1, r, x, y);return re;
}
bool chk(int x, int v) {node re;while(x) {if(x != top[x]) re = re + qry(1, 1, n, dfn[top[x]], dfn[fa[x]]);if((x = fa[top[x]])) re = re + qry(1, 1, n, dfn[x], dfn[x]).rev();}return re.a < v && v < re.b;
}
int main() {read(n), read(m);for(int i = 1; i <= n; ++i) {read(a[i]), read(ch[i][0]), read(ch[i][1]);if(ch[i][0]) fa[ch[i][0]] = i;if(ch[i][1]) fa[ch[i][1]] = i;}for(rt = 1; fa[rt]; ++rt);dfs1(rt); dfs2(rt, rt); build(1, 1, n);int op, x;while(m--) {read(op), read(x);if(op == 1)    read(a[x]), upd(1, 1, n, dfn[x]);else if(op == 2) mdf(1, 1, n, dfn[x], dfn[x]+sz[x]-1);else puts(chk(x, a[x]) ? "YES" : "NO");}
}

C.仙人掌

题解:f(i,j)f(i,j)f(i,j)表示圆方树上i的子树内的点的生成子图内的边完成了定向,i的出度为j的方案数,由于度数总和是O(n)O(n)O(n)的,所以状态数总和不会超过O(n)O(n)O(n)。转移分两类,一种是整个环的转移(即方点),枚举环上一条边的方向转移即可;另一种是合并若干个环或桥边的转移(即圆点),根据环最上方两条边的方向或是桥边的方向,是一个类似背包的DPDPDP,可以直接用分治NTTNTTNTT优化。时间复杂度O(nlog2⁡n)O(n log^2⁡n)O(nlog2⁡n)。

#include <bits/stdc++.h>
using namespace std;
char cb[1<<15], *cs=cb, *ct=cb;
#define getc() (cs==ct && (ct = (cs=cb) + fread(cb,1,1<<15,stdin), cs==ct) ? 0 : *cs++)
inline void read(int &x) {char ch; int flg=1; while(!isdigit(ch=getc()))if(ch=='-')flg=-flg;for(x=ch-'0';isdigit(ch=getc());x=x*10+ch-'0'); x*=flg;
}
const int MAXN = 530000;
const int mod = 998244353, G = 3;
int n, m, a[MAXN], du[MAXN], tot;
int Fir[MAXN], To[MAXN], Nxt[MAXN], Cnt = 1;
int fir[MAXN], to[MAXN], nxt[MAXN], cnt;
inline void link(int u, int v) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; }
inline void Add(int u, int v) { To[++Cnt] = v; Nxt[Cnt] = Fir[u]; Fir[u] = Cnt; }
int dfn[MAXN], low[MAXN], tmr, stk[MAXN], indx;
void tarjan(int u, int ff) {dfn[u] = low[u] = ++tmr; stk[++indx] = u;for(int i = Fir[u], v; i; i = Nxt[i])if(i^ff^1) {if(!dfn[v=To[i]]) {tarjan(v, i), low[u] = min(low[u], low[v]);if(low[v] == dfn[u]) {link(u, ++tot);do link(tot, stk[indx]);while(stk[indx--] != v);}else if(low[v] > dfn[u]) --indx, link(u, v);}else low[u] = min(low[u], dfn[v]);}
}
int f[MAXN][3];
#define pb push_back
int cur; vector<int>vec[MAXN];
inline void add(int &x, int y) { x = x + y >= mod ? x + y - mod : x + y; }
inline int pls(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }
int gen[MAXN], W, rev[MAXN], X[MAXN], Y[MAXN];
inline int qpow(int a, int b) {int re = 1; for(; b; b>>=1, a=1ll*a*a%mod)if(b&1) re=1ll*re*a%mod;return re;
}
void NTT(int *arr, int len, int flg) {for(int i = 0; i < len; ++i)if(rev[i]<i)swap(arr[i], arr[rev[i]]);for(int i = 2, v, B = W>>1; i <= len; i<<=1, B>>=1) //iB = Wfor(int j = 0; j < len; j+=i)for(int k = j, x = 0; k < j+i/2; ++k, x+=B)arr[k+i/2] = pls(arr[k], mod-(v = 1ll * arr[k+i/2] * gen[flg==1?x:W-x] % mod)), add(arr[k], v);if(flg == -1) {int iv = qpow(len, mod-2);for(int i = 0; i < len; ++i) arr[i] = 1ll * arr[i] * iv % mod;}
}
vector<int> cal(int l, int r) {if(l == r) return vec[l];int mid = (l + r) >> 1;vector<int>L = cal(l, mid), R = cal(mid+1, r);int len = 1, lb = L.size(), rb = R.size();while(len <= lb+rb-2) len<<=1;for(int i = 1; i < len; ++i)rev[i] = (rev[i>>1]>>1)|((i&1)*(len>>1));for(int i = 0; i < lb; ++i) X[i] = L[i];for(int i = lb; i < len; ++i) X[i] = 0;for(int i = 0; i < rb; ++i) Y[i] = R[i];for(int i = rb; i < len; ++i) Y[i] = 0;NTT(X, len, 1), NTT(Y, len, 1);for(int i = 0; i < len; ++i) X[i] = 1ll * X[i] * Y[i] % mod;NTT(X, len, -1);vector<int>re; re.resize(lb+rb-1);for(int i = 0, siz = re.size(); i < siz; ++i) re[i] = X[i];return re;
}
void getans(int *F, int A) {vector<int> re = cal(1, cur);re.resize(A+1);for(int i = 1; i <= A; ++i) add(re[i], re[i-1]);F[0] = re[A]; if(A > 0) F[1] = re[A-1]; if(A > 1) F[2] = re[A-2];
}
void dfs(int u) {for(int i = fir[u]; i; i = nxt[i]) dfs(to[i]);if(u <= n) {if(u == 5) {++u;--u;}if(!fir[u]) f[u][0] = 1, f[u][1] = a[u]>0, f[u][2] = a[u]>1;else {cur = 0;for(int i = fir[u], v; i; i = nxt[i]) {vec[++cur].clear();if((v=to[i]) > n) vec[cur].pb(f[v][2]);vec[cur].pb(f[v][1]), vec[cur].pb(f[v][0]);}getans(f[u], a[u]);}}else {for(int o = 0; o < 2; ++o) {int now[2] = { 0, 0 }, pre[2]; now[o] = 1;for(int i = fir[u], v; i; i = nxt[i]) {swap(now, pre); v = to[i];now[0] = (1ll * pre[0] * f[v][1] % mod + 1ll * pre[1] * f[v][2]) % mod;now[1] = (1ll * pre[0] * f[v][0] % mod + 1ll * pre[1] * f[v][1]) % mod;}(f[u][o] += now[1]) %= mod;(f[u][o+1] += now[0]) %= mod;}}
}
void pre(int N) {W = 1; while(W <= N) W<<=1;gen[0] = 1, gen[1] = qpow(G, (mod-1)/W);for(int i = 2; i <= W; ++i) gen[i] = 1ll*gen[i-1]*gen[1] % mod;
}
int main() {read(n), read(m); pre(2*(n-1));for(int i = 1, u, v; i <= m; ++i) read(u), read(v), Add(u, v), Add(v, u), ++du[u], ++du[v];for(int i = 1; i <= n; ++i) read(a[i]), a[i] = min(a[i], du[i]);tot = n; tarjan(1, 0); dfs(1);printf("%d\n", f[1][0]);
}

0522模拟赛 A. 求和 B.农民(farmer) C.仙人掌相关推荐

  1. 【普组模拟赛】马农(farmer.pas/cpp)

    [普组模拟赛]马农(farmer.pas/cpp) 题目描述: 在观看完战马检阅之后,来自大草原的两兄弟决心成为超级"马农",专门饲养战马. 兄弟两回到草原,将可以养马的区域,分为 ...

  2. 2020年 第11届 蓝桥杯 第2次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛真题详解及小结汇总[2013年(第4届)~2020年(第11届)] 注意:部分代码及程序 源自 蓝桥杯 官网视频(历年真题解析) 郑未老师. 2013年 第04届 蓝桥杯 ...

  3. 10.30 NFLS-NOIP模拟赛 解题报告

    总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...

  4. 省选模拟赛记录(越往下越新哦~~~)

    LOG 模拟赛 第一次见尼玛这么给数据范围的-- 开考有点困,迷迷糊糊看完了三道题,真的是像老吕说的那样,一道都不会-- 思考T1,感觉有点感觉,但是太困了,就先码了暴力,发现打表可以50分,于是就大 ...

  5. 2020.04.08【NOIP普及组】模拟赛C组24 总结

    2020.04.08 2020.04.08 2020.04.08[ N O I P NOIP NOIP普及组]模拟赛 C C C组 24 24 24 总结 概述: 这次比赛我 A K AK AK了,拿 ...

  6. 第十三届蓝桥杯模拟赛(第三期)试题与题解 C++

    文章目录 第十三届蓝桥杯模拟赛(第三期)试题与题解 1.试题A 题解:数制转换 2.试题B 题解:枚举 3.试题C 题解:枚举 4.试题D 题解:最小生成树 5.试题E 方法一:暴力求和 方法二:一维 ...

  7. 第十四届蓝桥杯模拟赛第一期试题【Java解析】

    目录 A 二进制位数 问题描述 答案提交 参考答案 解析 B 晨跑 问题描述 答案提交 参考答案 解析 C 调和级数 问题描述 答案提交 参考答案 解析 D 山谷 问题描述 答案提交 参考答案 解析 ...

  8. 第十四届蓝桥杯第一期模拟赛试题与题解 C++

    第十四届蓝桥杯第一期模拟赛试题与题解 C++ 试题 A 题解:位运算 试题 B 题解:日历模拟 试题 C 题解:double 求和 试题 D 题解:枚举 试题 E 题解:二维前缀和 试题 F 题解:两 ...

  9. CSP-J 2022年8月第一轮模拟赛 1

    CSP-J 第一轮模拟赛 1 一. 判断题(每题 1 分,共 10 分,选项 T=正确, F=错误,每空标号处均填选择的答案对应的大写字母) 1.  CSP-J/S 非专业级别比专业级别更难(  ) ...

最新文章

  1. Mysql 内部结构 / Replication | 原理
  2. 基于redis的分布式锁解析
  3. 不擅长物理科学计算机吗,物理难学否?答案因人而异,高二同学3 + 3选科莫要太随意...
  4. 【转】python2与python3的主要区别
  5. (转载)机器学习知识点(十五)从最大似然到EM算法浅解
  6. 搜索引擎利用机器学习排序
  7. mongodb基本语法
  8. linux下Oracle 10g安装(超级详细图解教程)
  9. qt怎么可以随意设置自己想要的表格_【Qt开发】QTableWidget的详细设置
  10. WSUS离线导入更新包
  11. Java面试题系列(X)锁的原理
  12. 25. k个一组翻转链表
  13. 数据仓库和Hadoop大数据平台有什么差别?
  14. c语言的sin cos是弧度,C++中cos,sin,asin,acos這些三角函數操作的是弧度,而非角度(轉)...
  15. jQuery实现打地鼠游戏
  16. 微信挪车功能成功上线,祝贺一下自己
  17. 斜杠 反斜杠  双斜杠 双反斜杠
  18. 【jquery】Chosen.jquery.js 插件动态加载数据问题
  19. 1.1.6 LSDB同步
  20. Linux-C C语言编译过程

热门文章

  1. 【转】初入NLP领域的一些小建议
  2. Python学习笔记——selenium无头模式
  3. 《国家宝藏》甘肃省博物馆专场:杜淳、黄轩演绎丝路传奇
  4. 杭电计算机专硕报考人数,杭电考研各科目考试工具规定公布,它的报考人数却……...
  5. php.ini 关闭输出缓冲,php 输出缓冲 Output Control用法实例详解
  6. 接口测试的标准和规范性
  7. SpringBoot整合JavaMail通过阿里云企业邮箱发送邮件
  8. C#winform 经典小游戏贪吃蛇V1.0(一)
  9. 学生身份你可以干什么?
  10. 【原创】描述性分析思维的一些基本思路与见解