LOJ刷题记录:2024-2029(SHOI2016)
来源:互联网 发布:淘宝卖家火拼在哪里 编辑:程序博客网 时间:2024/06/05 10:26
LOJ刷题记录:2024-2029(SHOI2016)
loj#2024. 「JLOI / SHOI2016」侦查守卫
设
- 这个节点放一个
- 这个节点不放
要分开判断是欠着还是富余…
然后就是码农题了..
#include <bits/stdc++.h>using namespace std;const int MAXN = 500005;struct node { int to, next;} edge[MAXN*2];int head[MAXN], top = 0;inline void push(int i, int j){ edge[++top] = (node) {j, head[i]}, head[i] = top;}int f[MAXN][45]; // f[nd][k] --> nd这个子树,至少覆盖到包括nd上面k层;若k<0,则表示不包括nd,下面-k层已经被覆盖int w[MAXN], hav[MAXN];int n, m, d;void dfs(int nd, int fa){ int sd[45]; memset(sd, 0, sizeof sd); for (register int i = head[nd]; i; i = edge[i].next) { if (edge[i].to == fa) continue; dfs(edge[i].to, nd); for (int j = -d; j <= d+1; j++) sd[j+22] += f[edge[i].to][j+22]; } for (register int k = -d; k <= d+1; k++) { f[nd][k+22] = w[nd]; for (register int i = head[nd]; i; i = edge[i].next) { if (edge[i].to == fa) continue; f[nd][k+22] += f[edge[i].to][-d+1+22]; } if (k <= 0) f[nd][k+22] = min(f[nd][k+22], sd[k+1+22]); if (k == 1 && !hav[nd]) f[nd][k+22] = min(f[nd][k+22], sd[1+22]); int need = k; if (k != 1 || hav[nd]) need++; if (need < 1) need = 1; for (register int i = head[nd]; i; i = edge[i].next) { // 有干扰,枚举干扰节点 if (edge[i].to == fa) continue; for (register int j = max(need, 2); j <= d+1; j++) { f[nd][k+22] = min(f[nd][k+22], f[edge[i].to][j+22]+sd[3-j+22]-f[edge[i].to][3-j+22]); } } }}int main(){ memset(f, -1, sizeof f); scanf("%d%d", &n, &d); for (int i = 1; i <= n; i++) scanf("%d", &w[i]); scanf("%d", &m); for (register int i = 1; i <= m; i++) { int u; scanf("%d", &u); hav[u] = 1; } for (register int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); push(u, v), push(v, u); } dfs(1, 0); printf("%d\n", f[1][1+22]); return 0;}
loj#2027. 「SHOI2016」黑暗前的幻想乡
SH·数数大赛·OI….
枚举子集,然后用矩阵树算一算…再容斥起来。复杂度及其不科学..然而跑得比谁都快
#include <bits/stdc++.h>using namespace std;const int MAXN = 20, mod = 1e9+7;int n;vector<pair<int, int> > M[MAXN];int g[MAXN][MAXN];inline int power(int a, int n){ int ans = 1; for (int i = 0; i <= 30; i++) { if (n&(1<<i)) ans = (long long)ans*a%mod; a = (long long)a*a%mod; } return ans;}inline int inv(int a){ return power(a, mod-2); }int gauss(){ int flag = 1; for (int i = 1; i < n; i++) { int pos = i; while (pos < n && !g[pos][i]) pos++; if (pos == n) return 0; if (pos != i) swap(g[pos], g[i]), flag *= -1; for (int j = 1; j < n; j++) { if (j == i) continue; int tmp = ((-(long long)g[j][i]*inv(g[i][i]))%mod+mod)%mod; for (int k = 1; k < n; k++) g[j][k] = (g[j][k]+(long long)g[i][k]*tmp)%mod; } } for (int i = 1; i < n; i++) flag = (long long)flag*g[i][i]%mod; return (flag+mod)%mod;}int main(){ scanf("%d", &n); for (int i = 1; i < n; i++) { int mi, u, v; scanf("%d", &mi); for (int j = 1; j <= mi; j++) { scanf("%d%d", &u, &v); M[i].push_back(make_pair(u, v)); } } int ans = 0; for (int i = 0; i < (1<<(n-1)); i++) { int num = 0; memset(g, 0, sizeof g); for (int j = 1; j < n; j++) { if (!(i&(1<<(j-1)))) continue; num++; for (int k = 0; k < M[j].size(); k++) { int u = M[j][k].first, v = M[j][k].second; g[u][v]--, g[v][u]--, g[u][u]++, g[v][v]++; } } if ((n-1-num)&1) ans -= gauss(); else ans += gauss(); ((ans %= mod) += mod) %= mod; } printf("%d\n", ans); return 0;}
loj#2028. 「SHOI2016」随机序列
每一个加号都会有一个减号消掉他,所以贡献只来源于第一个加减前面的..所以直接维护就好了。
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005, mod = 1e9+7;int n, q;int arr[MAXN];int a[MAXN*4];int lc[MAXN*4], rc[MAXN*4], l[MAXN*4], r[MAXN*4], root, top = 0, dat[MAXN*4];int tag[MAXN*4];int power(int a, int n){ int ans = 1; for (int i = 0; i <= 30; i++) { if (n&(1<<i)) ans = (long long)ans*a%mod; a = (long long)a*a%mod; } return ans;}int inv(int a){ return power(a, mod-2); }void build(int &nd, int opl, int opr){ nd = ++top, l[nd] = opl, r[nd] = opr, tag[nd] = 1; if (opl == opr) dat[nd] = a[opl]; else { int mid = (l[nd]+r[nd])>>1; build(lc[nd], opl, mid), build(rc[nd], mid+1, opr); dat[nd] = (dat[lc[nd]]+dat[rc[nd]])%mod; }}void pdw(int nd){ if (lc[nd]) tag[lc[nd]] = (long long)tag[nd]*tag[lc[nd]]%mod, tag[rc[nd]] = (long long)tag[nd]*tag[rc[nd]]%mod; dat[nd] = (long long)dat[nd]*tag[nd]%mod, tag[nd] = 1;}void modify(int nd, int opl, int opr, int dt){ // cerr << nd << " " << opl << " " << opr << " " << dt << endl; pdw(nd); if (l[nd] == opl && r[nd] == opr) tag[nd] = (long long)tag[nd]*dt%mod; else { int mid = (l[nd]+r[nd])/2; if (opr <= mid) modify(lc[nd], opl, opr, dt); else if (opl > mid) modify(rc[nd], opl, opr, dt); else modify(lc[nd], opl, mid, dt), modify(rc[nd], mid+1, opr, dt); pdw(lc[nd]), pdw(rc[nd]); dat[nd] = (dat[lc[nd]]+dat[rc[nd]])%mod; }}int main(){ // cerr << (long long)2414*inv(2414)%mod << endl; scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) scanf("%d", &arr[i]); int mul = 1; for (int i = 1; i <= n; i++) { mul = (long long)mul*arr[i]%mod; if (i < n) a[i] = (long long)mul*2*power(3, n-i-1)%mod; else a[i] = mul; } build(root, 1, n); // cerr << dat[root] << endl; for (int i = 1; i <= q; i++) { int t, v; scanf("%d%d", &t, &v); modify(root, t, n, (long long)inv(arr[t])*v%mod), arr[t] = v; pdw(root), printf("%d\n", dat[root]); } return 0;}
阅读全文
0 0
- LOJ刷题记录:2024-2029(SHOI2016)
- LOJ刷题记录:SHOI2016(2036-2041)
- LOJ刷题记录:2030-2035(SDOI2016)
- LOJ刷题记录:2000-2005(SDOI2017)
- LOJ刷题记录:2006-2011(SCOI2015)
- LOJ刷题记录:2012-2017(SCOI2016)
- LOJ刷题记录:2018-2020
- 每周刷题记录(持续更新)
- 牛客剑指offer刷题记录(一)
- 牛客剑指offer刷题记录(二)
- 牛客剑指offer刷题记录(三)
- 牛客剑指offer刷题记录(四)
- 牛客剑指offer刷题记录(五)
- 牛客剑指offer刷题记录(六)
- 牛客剑指offer刷题记录(七)
- OI刷题记录
- OI刷题记录~
- leetcode刷题记录
- oracle学习(dbca命令参数)
- 第6章 访问权限控制
- Git如何存储内容
- PAT1007. 素数对猜想 (20)
- 2.4 多态和虚函数
- LOJ刷题记录:2024-2029(SHOI2016)
- Maven学习笔记---配置eclipse中maven环境
- MOOC清华《面向对象程序设计》第4章:函数模板的特化实验
- Java基础问题:输入一个数字获取对应范围及长度的所有不重复的数字,例如:输入3.则输出{123,132,213,231,321,312}
- DramWeaver编辑器
- python连接mysql
- Android客户端之“微服私访”App的系统学习(八)调用系统摄像头拍照并管理照片并使用Okhttp上传文件至后台
- HDU3333
- 2.5 运算符重载