BJOI 模拟赛 #3 题解
T1
一个网格,每个点有权值,求有多少条路径权值乘积不小于 $n$
$R,C \leq 300, n \leq 10^6$
sol:
暴力 dp 是 $O(R \times C \times n)$ 的
然后发现如果一条路径大于 $n$ ,直接把它设成 $n$ 即可,然后又发现 $\lfloor \frac{n}{i} \rfloor$ 只有 $O(\sqrt{n})$ 种取值,记录一下即可做到 $O(R \times C \times \sqrt{n})$
#include <bits/stdc++.h>
#define Debug(x) cerr << #x << " = " << x << '\n'
#define debug(x) cerr << #x << " = " << x
#define TAB << " "
#define EDL << "\n"
#define LL long long
#define rep(i, s, t) for(register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for(register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = , f = ; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -f;
for(; isdigit(ch); ch = getchar()) x = * x + ch - '';
return x * f;
}
const int mod = 1e9 + , maxn = ;
int n, m, q, stk[], top, bl[];
int a[maxn][maxn], dp[][maxn][];
inline void mo(int &x) { if(x >= mod) x -= mod; if(x < ) x += mod; }
int main() {
//freopen("mobitel.in","r",stdin);
//freopen("mobitel.out","w",stdout);
n = read(), m = read(), q = read(); q--;
rep(i, , n) rep(j, , m) a[i][j] = read();
for(int l = , r; l <= q; l = r + ) r = q / (q / l), stk[++top] = q / r, bl[q / r] = top;
// Debug(top);
stk[++top] = , bl[] = top;
int now = q;
rep(i, , m) {
now /= a[][i], dp[][i][bl[now]] = ;
//debug(i) TAB; debug(now) TAB; debug(a[1][i]) EDL;
}
//Debug(now);
int cur = , last = ;
rep(i, , n) {
last = cur, cur = cur ^ ;
memset(dp[cur], , sizeof(dp[cur]));
//Debug(cur);
rep(j, , m) {
// assert(a[i][j] != 0);
rep(k, , top) {
//assert(a[i][j] != 0);
dp[cur][j][bl[stk[k] / a[i][j]]] += dp[last][j][k];
mo(dp[cur][j][bl[stk[k] / a[i][j]]]);
if(j != m) {
dp[cur][j + ][bl[stk[k] / a[i][j + ]]] += dp[cur][j][k];
mo(dp[cur][j + ][bl[stk[k] / a[i][j + ]]]);
}
//debug(i) TAB; debug(j) TAB; debug(k) EDL;
}
}
} cout << dp[cur][m][top] << endl;
}
T2
一个有点权和边权的树,一条简单路径合法当且仅当对于这个路径的每一个非空前缀都满足点权大于等于边权,求有多少合法简单路径
$n \leq 100000$
sol:
点分治,预处理一下子树里每个点到重心会剩下多少点权,重心到子树里每个点还需要多少点权,在重心处双指针合并一下,容斥即可
#include <bits/stdc++.h>
#define LL long long
#define debug(x) cerr << #x << " = " << x
#define TAB cerr << " "
#define EDL cerr << endl
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = ,f = ; char ch = getchar();
for(; !isdigit(ch); ch = getchar())if(ch == '-') f = -f;
for(; isdigit(ch); ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = ;
int n, a[maxn];
LL ans;
int first[maxn], to[maxn << ], nx[maxn << ], val[maxn << ], cnt;
inline void add(int u, int v, int w) {
to[++cnt] = v;
nx[cnt] = first[u];
first[u] = cnt;
val[cnt] = w;
}
int root, sig, ff[maxn], size[maxn], vis[maxn];
void findroot(int x, int pre) {
ff[x] = ; size[x] = ;
for(int i=first[x];i;i=nx[i]) {
if(to[i] == pre || vis[to[i]]) continue;
findroot(to[i], x); size[x] += size[to[i]];
ff[x] = max(ff[x], size[to[i]]);
}
ff[x] = max(ff[x], sig - size[x]);
if(ff[x] < ff[root]) root = x;
}
LL f[maxn], g[maxn]; int fl, gl;
void calup(int x, int pre, LL cur, LL mx) {
if(a[x] >= mx) f[++fl] = (a[x] + cur); mx -= a[x], cur += a[x];
for(int i=first[x];i;i=nx[i]) {
if(vis[to[i]] || to[i] == pre) continue;
calup(to[i], x, cur - val[i], max(mx + val[i], (LL)val[i]));
}
}
void caldw(int x, int pre, LL cur, LL mn) {
//debug(mn); TAB; debug(cur); EDL;
g[++gl] = mn; cur += a[x];
for(int i=first[x];i;i=nx[i]) {
if(vis[to[i]] || to[i] == pre) continue;
caldw(to[i], x, cur - val[i], min(mn, cur - val[i]));
}
}
void merge(int opt) {
int tmp = , pos = fl; LL res = ;
//cerr << fl << " " << gl << endl;
// debug(fl); TAB; debug(gl); EDL;
sort(f + , f + fl + ); sort(g + , g + gl + );
rep(i, , gl) {
while(pos && g[i] + f[pos] >= ) tmp++, pos--;
res += tmp;
} ans += opt * res;
// debug(ans);
}
void solve(int x) {
fl = gl = ;
vis[x] = ; caldw(x, , , ); calup(x, , -a[x], ); merge(); ans--;
for(int i=first[x];i;i=nx[i]) {
if(vis[to[i]]) continue; fl = gl = ;
caldw(to[i], x, a[x] - val[i], a[x] - val[i]);
calup(to[i], x, -val[i], val[i]); merge(-);
}
for(int i=first[x];i;i=nx[i]) {
if(vis[to[i]]) continue;
root = ; sig = size[to[i]];
findroot(to[i], x); solve(root); //debug(root);
}
}
int main() {
//freopen("transport.in","r",stdin);
//freopen("transport.out","w",stdout);
n = read();
rep(i, , n) a[i] = read();
rep(i, , n) {
int u = read(), v = read(), w = read();
add(u, v, w); add(v, u, w);
} ff[] = ; sig = n;
findroot(, ); solve(root); //debug(root);
cout << ans << endl;
}
T3
有一个游戏,你有 $n$ 个对手,每轮你可以淘汰一些对手,然后拿到 $\frac{淘汰人数}{总人数}$ 的钱,现在你只能进行 $k$ 轮,求最多能拿多少钱
$n,k \leq 100000$
sol:
容易知道钱数随 $k$ 是单调的,所以可以使用带权二分
二分一个权值,表示如果多选一轮需要额外花多少钱
然后用 $f_i$ 表示你已经淘汰了前 $i$ 个对手需要花多少钱,然后看当前轮数是否大于 $k$ ,大于 $k$ 就增加权值,小于 $k$ 就减少权值
然后就过了
#include <bits/stdc++.h>
#define LL long long
#define DB long double
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
#define DEBUG
using namespace std;
inline int read() {
int x = , f = ; char ch;
for (ch = getchar(); !isdigit(ch); ch = getchar()) if (ch == '-') f = -f;
for (; isdigit(ch); ch = getchar()) x = * x + ch - '';
return x * f;
}
const int maxn = ;
int n, k, HD, TL, q[maxn], pre[maxn], nx[maxn];
DB f[maxn];
//f[i] = max{f[j] - j / (n - j) + i / (n - j)} + mid;
inline DB Y(int j) { return f[j] - (1.00 * (DB)j) / (1.00 * ((DB)n - (DB)j)); }
inline DB X(int j) { return 1.00 / (1.00 * ((DB)n - (DB)j)); }
inline DB slope(int j, int i) { return (Y(i) - Y(j)) / (X(i) - X(j)); }
inline int check(DB mid, int opt = ) {
memset(f, , sizeof(f));
memset(pre, , sizeof(pre));
memset(nx, , sizeof(nx));
memset(q, , sizeof(q));
q[TL = HD = ] = ;
rep(i, , n) {
while(HD < TL && slope(q[HD], q[HD + ]) >= (DB)(-i)) ++HD;
int pos = q[HD];
f[i] = f[pos] + (1.00 * (i - pos)) / (1.00 * (n - pos)) - mid;
pre[i] = pos;
while(HD <= TL && slope(q[TL], q[TL - ]) <= slope(q[TL], i)) --TL;
q[++TL] = i;
#ifdef DEBUG
if(opt)cout << i << " " << pos << endl;
#endif
} //system("pause");
int cur = n, cnt = ;
while(cur) {
cnt++; nx[pre[cur]] = cur;
cur = pre[cur];
//cout << cur << endl;
}
// cout << cnt << " " << k << endl;
//return cnt > k;
return cnt;
}
int main() {
#ifndef DEBUG
freopen("quiz.in","r",stdin);
freopen("quiz.out","w",stdout);
#endif
n = read(), k = read();
DB l = , r = , mid;
rep(t, , ) {
mid = (l + r) / 2.0; int now;
if((now = check(mid)) > k) l = mid;
else if(now < k) r = mid;
else break;
} check(mid, ); double ans = f[n] + k * mid;
cout << fixed << showpoint << setprecision() << ans << endl;
}
BJOI 模拟赛 #3 题解的更多相关文章
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 2020.3.23 模拟赛游记 & 题解
这次的模拟赛,实在是水. 数据水,\(\texttt{std}\) 水,出题人水,做题人也水.??? 游记就说一句: 水. T1 metro 弱智题. 人均 \(100pts\). #pragma G ...
- BJOI 2019 模拟赛 #2 题解
T1 完美塔防 有一些空地,一些障碍,一些炮台,一些反射镜 障碍会挡住炮台的炮, 反射镜可以 90° 反射炮台的光线,炮台可以选择打他所在的水平一条线或者竖直一条线 求是否有一组方案满足每个空地必须要 ...
- 洛谷[LnOI2019]长脖子鹿省选模拟赛 简要题解
传送门 听说比赛的时候T4T4T4标程锅了??? WTF换我时间我要写T3啊 于是在T4T4T4调半天无果的情况下260pts260pts260pts收场真的是tcltcltcl. T1 快速多项式变 ...
- NOIP模拟赛10 题解
t3: 题意 给你一棵树,然后每次两种操作:1.给一个节点染色 : 2. 查询一个节点与任意已染色节点 lca 的权值的最大值 分析 考虑一个节点被染色后的影响:令它的所有祖先节点(包括自身)的所有除 ...
- 【CYH-02】noip2018数论模拟赛:赛后题解
1.小奔的矩阵 2.大奔的方案 3.小奔与不等四边形 4.小奔的方案 当然本次比赛肯定难度不会仅限于此啦!后续还会--
- bsoj5988 [Achen模拟赛]期望 题解
bsoj5988 Description [题目背景] NOI2018 已经过去了许久,2019 届的 BSOIer 们退役的退役,颓废的颓废,计数能力大不如前.曾经的数数之王 xxyj 坦言:&qu ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP第7场模拟赛题解
NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...
随机推荐
- Win10m的前景到底在何方?
今天晚上就是build2016的微软开发者大会了,满怀着期待. 本人一直是一名微软的粉丝,我年纪小,刚开始接触电脑的时候是win98,那时候也没怎么玩过电脑,到后来经常接触电脑的时候,所有的电脑都是w ...
- Vuex最基本样例
通过vue-cli建立基本脚手架(需要安装vuex),需要新建一个store.js文件.基本目录如下 1,store.js文件代码: import Vue from 'vue' import Vuex ...
- spring mvc: rss(xml)输出
准备: rss包插件 Rome 库及其依赖项rome-utils,jdom和slf4j <!-- rss源依赖 --> <!-- https://mvnrepository.com/ ...
- IdentityServer4在Asp.Net Core中的应用(一)
IdentityServer4是一套身份授权以及访问控制的解决方案,专注于帮助使用.Net 技术的公司为现代应用程序建立标识和访问控制解决方案,包括单点登录.身份管理.授权和API安全. 下面我将具体 ...
- ASP.NET 4.5 MVC 4 无法运行在Windows2008的IIS7.0上显示404的解决方案
需要在web.config下加上这个 <system.webServer> <modules runAllManagedModulesForAllRequests="tru ...
- Spring3.0 核心jar包详解
org.springframework.aop 包含在应用中使用Spring的AOP特性时所需的类. org.springframework.asm Spring独立的ASM程序, Spring ...
- ubuntu中python2与python3的默认启动切换
方法摘自SegmentFault: 方法一: echo alias python=python3 >> ~/.bashrc && source ~/.bashrc相当于先打 ...
- linux下鼠标穿透和取消穿透--linux小白,大神无视
最近在用qt写一个跨平台的软件,因为设置了无边框,并且我自己给程序窗口加了阴影,阴影范围又比较大 所以必须给阴影区域加上鼠标穿透才能有更好的体验. 上网查了一下,在windows下使用SetWindo ...
- EasyUI Combobox 组合框
默认选择第一项,加请选择,取值问题 <input class="easyui-combobox" id="ddlWHS" name="ddlWH ...
- gitblit-部署
什么是 Gitblit Gitblit是一个开源的用于管理,查看和提供Git仓库. 它主要设计为希望托管集中存储库的小工作组的工具. Gitblit有什么特点 Gitblit部署示例1 日常维护添加步 ...