Prob. 1

Desc. & Link.

行走的形式是比较自由的,因为只要走到了最优答案处就可以不管了,所以不需要考虑游戏的结束。

考虑二分答案。

然后预处理出每个节点到 \(s\)(另一棵树就是 \(t\))的距离。

判断答案合法性:

首先枚举 \(A\) 树的每个节点(节点编号小于当前二分的答案),然后判断需要构成答案的 \(B\) 树上的节点距离 \(t\) 的距离的奇偶性是否一致即可。

但是这样有一个问题:我们如何确保这个答案是整个一轮移动过程中最大的?

仔细考虑一下,我们判断成功的依据是行走过程中所有和不超过我们当前二分的值,那么转为判断这个问题(意思就是前面降智了)。

因为这是一棵树,所以该走的路径一定会走。

因为我们枚举了 \(A\) 树中的节点,所以每次从哪两个节点走到 \(s\)、\(t\) 是固定下来的。

草,直接 bfs 判断找可达最小值就行了。

\(\Theta(n\log_{2}^{2}n)\),我觉得不行,先写。

草卡卡常过了。

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include <cstdio>
#include <queue> using namespace std; const int MAXN = 1e6 + 5; namespace IO{
const int sz=1<<22;
char a[sz+5],b[sz+5],*p1=a,*p2=a,*t=b,p[105];
inline char gc(){
return p1==p2?(p2=(p1=a)+fread(a,1,sz,stdin),p1==p2?EOF:*p1++):*p1++;
}
template<class T> void gi(T& x){
x=0; char c=gc();
for(;c<'0'||c>'9';c=gc());
for(;c>='0'&&c<='9';c=gc())
x=x*10+(c-'0');
}
inline void flush(){fwrite(b,1,t-b,stdout),t=b; }
inline void pc(char x){*t++=x; if(t-b==sz) flush(); }
template<class T> void pi(T x,char c='\n'){
if(x==0) pc('0'); int t=0;
for(;x;x/=10) p[++t]=x%10+'0';
for(;t;--t) pc(p[t]); pc(c);
}
struct F{~F(){flush();}}f;
}
using IO::gi;
using IO::pi; template<typename _T> _T MIN ( const _T x, const _T y ) { return x < y ? x : y; } struct GraphSet {
int to, nx;
GraphSet ( int T = 0, int N = 0 ) { to = T, nx = N; }
} asA[MAXN * 2], asB[MAXN * 2]; int n, s, t, cntA, cntB, beginA[MAXN], beginB[MAXN], disA[MAXN], disB[MAXN], visA[MAXN], visB[MAXN]; void makeEdgeA ( const int u, const int v ) { asA[++ cntA] = GraphSet ( v, beginA[u] ), beginA[u] = cntA; }
void makeEdgeB ( const int u, const int v ) { asB[++ cntB] = GraphSet ( v, beginB[u] ), beginB[u] = cntB; } void dfsA ( const int u, const int lst, const int dis ) {
disA[u] = dis;
for ( int i = beginA[u]; i; i = asA[i].nx ) {
int v = asA[i].to;
if ( v == lst ) continue;
dfsA ( v, u, dis + 1 );
}
} void dfsB ( const int u, const int lst, const int dis ) {
disB[u] = dis;
for ( int i = beginB[u]; i; i = asB[i].nx ) {
int v = asB[i].to;
if ( v == lst ) continue;
dfsB ( v, u, dis + 1 );
}
} void behaveOneSide ( int ark, int& mnA, int& mnB, int& ord, priority_queue<int, vector<int>, greater<int>>& align ) {
int preSave = mnA;
while ( ! align.empty () ) {
int u = align.top ();
if ( u + mnB > ark ) break;
else align.pop ();
for ( int i = beginA[u]; i; i = asA[i].nx ) {
int v = asA[i].to;
if ( visA[v] ) continue;
visA[v] = 1, align.push ( v );
mnA = MIN ( mnA, v );
}
}
if ( mnA == preSave ) ++ ord;
else ord = 0;
} void behaveAnotherSide ( int ark, int& mnA, int& mnB, int& ord, priority_queue<int, vector<int>, greater<int>>& align ) {
int preSave = mnB;
while ( ! align.empty () ) {
int u = align.top ();
if ( u + mnA > ark ) break;
else align.pop ();
for ( int i = beginB[u]; i; i = asB[i].nx ) {
int v = asB[i].to;
if ( visB[v] ) continue;
visB[v] = 1, align.push ( v );
mnB = MIN ( mnB, v );
}
}
if ( mnB == preSave ) ++ ord;
else ord = 0;
} priority_queue<int, vector<int>, greater<int>> oneQ, anotherQ;
bool check ( const int x ) {
for ( int i = 1; i <= n; ++ i ) visA[i] = visB[i] = 0;
for ( ; ! oneQ.empty (); oneQ.pop () ) ;
for ( ; ! anotherQ.empty (); anotherQ.pop () ) ;
oneQ.push ( s ), anotherQ.push ( t );
visA[s] = 1, visB[t] = 1;
int turn = 0, mnA = s, mnB = t, ord = 0;
while ( mnA > 1 || mnB > 1 ) {
turn ^= 1;
if ( turn ) behaveOneSide ( x, mnA, mnB, ord, oneQ );
else behaveAnotherSide ( x, mnA, mnB, ord, anotherQ );
if ( ord > 2 ) break;
}
if ( mnA == 1 && mnB == 1 ) return 1;
else return 0;
} int solve ( int l, int r ) {
while ( l + 1 < r ) {
int mid = ( l + r ) >> 1;
if ( check ( mid ) ) r = mid;
else l = mid;
}
return r;
} int main () {
int tCase;
gi ( tCase );
while ( tCase -- > 0 ) {
gi ( n ), cntA = cntB = 0;
for ( int i = 1; i <= n; ++ i ) beginA[i] = 0, beginB[i] = 0;
for ( int i = 1, u, v; i < n; ++ i ) {
gi ( u ), gi ( v );
makeEdgeA ( u, v ), makeEdgeA ( v, u );
}
for ( int i = 1, u, v; i < n; ++ i ) {
gi ( u ), gi ( v );
makeEdgeB ( u, v ), makeEdgeB ( v, u );
}
gi ( s ), gi ( t );
// dfsA ( s, 0, 0 ), dfsB ( t, 0, 0 );
pi ( solve ( 1, n << 1 ) );
}
return 0;
}

Prob. 2

Desc. & Link.

\(n\) 很小,\(q\) 也很小。

感觉这个 \(n\) 不是 \(2^{n}\) 的算法也不是多项式算法欸。

但复杂度一定与 \(n\) 有关……

草这玩意儿折半是不是可以折半搜索?

我们可以搜出两边我们可以凑出的价格,分别记为 \(A_{i},i\in[1,C_{A}]\)、\(B_{i},i\in[1,C_{B}]\)。

然后让 \(A,B\) sorted。

然后枚举 \(A_{i}\),找到 \(B\) 中最大的能与 \(A_{i}\) 相加小于等于需要的值,然后算下贡献即可(bullshit)。

不是为什么用快读本地过数据提交瓦爆啊。。。

#include<cstdio>
#include<algorithm>
using namespace std;
void read(long long &hhh)
{
long long x=0;
char c=getchar();
while(((c<'0')|(c>'9'))&(c^'-')) c=getchar();
if(c^'-') x=c^'0';
char d=getchar();
while((d>='0')&(d<='9'))
{
x=(x<<3)+(x<<1)+(d^'0');
d=getchar();
}
if(c^'-') hhh=x;
else hhh=-x;
}
void writing(long long x)
{
if(!x) return;
if(x>9) writing(x/10);
putchar((x%10)^'0');
}
void write(long long x)
{
if(x<0)
{
putchar('-');
x=-x;
}
else if(!x)
{
putchar('0');
putchar('\n');
return;
}
writing(x);
putchar('\n');
}
long long n,q,endone,beginano,onesiz,onebuc[2000005],anosiz,anobuc[2000005],opl,opr,cud[45];
void dfs(long long now,long long cur)
{
if(now==endone+1) onebuc[++onesiz]=cur;
else
{
dfs(now+1,cur+cud[now]);
dfs(now+1,cur);
}
}
void exdfs(long long now,long long cur)
{
if(now==n+1) anobuc[++anosiz]=cur;
else
{
exdfs(now+1,cur+cud[now]);
exdfs(now+1,cur);
}
}
long long solve(long long mos)
{
long long now=anosiz;
long long res=0;
for(long long i=1;i<=onesiz;++i)
{
while(now&&onebuc[i]+anobuc[now]>mos) now--;
res+=now;
}
return res;
}
int main()
{
// read(n);
// read(q);
scanf("%lld%lld",&n,&q);
// for(long long i=1;i<=n;++i) read(cud[i]);
for(long long i=1;i<=n;++i) scanf("%lld",&cud[i]);
endone=(n>>1);
beginano=endone+1;
dfs(1,0);
exdfs(beginano,0);
sort(onebuc+1,onebuc+onesiz+1);
sort(anobuc+1,anobuc+anosiz+1);
while(q--)
{
scanf("%lld%lld",&opl,&opr);
// read(opl);
// read(opr);
// write(solve(opr)-solve(opl-1));
printf("%lld\n",solve(opr)-solve(opl-1));
}
return 0;
}

Prob. 4

Desc. & Link.

相当于在树上对于每一个点找出找出一条以其为链顶的链。

设 \(f_{u}\) 为 \(u\) 的答案。

\[f_{u}=\max_{v\in\text{son}(u)}\{f_{v}+(a_{u}-\text{dis}(u,v))\times b_{v},0\}
\]

有乘法,然后题目中一堆常数。

斜率优化

我们令 \(s_{u}=\text{dis}(1,u)\),然后

\[\begin{aligned}
f_{u}
&=\max_{v\in\text{son}(u)}\{f_{v}+(a_{u}+s_{u}-s_{v})\times b_{v},0\} \\
&=\max_{v\in\text{son}(u)}\{(a_{u}-s_{u})\times b_{v}+f_{v}-s_{v}\times b_{v},0\}
\end{aligned}
\]

令 \(y=f_{u},x=a_{u}-s_{u},k=b_{v},b=f_{v}-s_{v}\times b_{v}\),那么这个东西就是一个 \(y=kx+b\)。

那么我们现在需要在子树里维护凸包,并且能够支持合并凸包和插入直线。

Record - Dec. 1st, 2020 - Exam. REC的更多相关文章

  1. 安装 uwsgi报错解决

    背景: 安装 uwsgi时报错如下,查阅相关资料说是 python-devel的问题,于是安装之后python-devel后问题解决 报错如下: (venv) [xxxxxxx]# pip insta ...

  2. anaconda环境---ubuntu下重装

    anaconda环境---ubuntu下重装 @wp20190312 为何重装? 配置一个环境,意外发现conda命令不好用了,提示“找不到conda模块”,整个conda虚拟环境中的工程项目无法使用 ...

  3. docker-容器完整构建过程

    container 代码app,构建,运行,分享(推送)image mkdir img1 cd img1 [root@cu-tmp-201 img1]# ls app.py Dockerfile re ...

  4. Python第五十一天 python2升级为python3

    Python第五十一天  python2升级为python3 公司使用的生产环境系统是centos7,所以这里以centos7系统为基础,讲解将python2升级为python3的方法 centos7 ...

  5. 容器编排工具之Docker-compose

    前文我们聊了下docker私有仓库harbor的搭建,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13061984.html:在上一篇博客的末尾,我们简单聊了 ...

  6. 视频直播点播nginx-rtmp开发手册中文版

    2016年8月18日12:42:35 参照官方文档https://github.com/arut/nginx-rtmp-module/wiki/Directives 请注意这个是粗翻译版,仅供参考,不 ...

  7. C++文件输入和输出

    1.引入头文件fstreamfstream头文件定义了用于文件输入的类ifstream和文件输出的类ofstream 2.写文件1)创建一个ofstream对象来管理输出流2)将该对象与文件关联起来3 ...

  8. Hide a Subpage Using PeopleCode

     There was a question asked on the forum on how to hid a subpage. There is no Peoplecode function to ...

  9. 锁大全与 GDB调试

    1.innodb_lock_monitor:打开锁信息的方式 mysql> create table innodb_lock_monitor(id int) engine=InnoDB; Que ...

  10. 浅谈Manacher算法与扩展KMP之间的联系

    首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解.网上解法颇多.时间复杂度也不尽同样,这里列述几种常见的解法. 解法一   ...

随机推荐

  1. 使用镜像加速 Rtools 下载与安装

    在 windows 使用 R,尤其是安装 R 包的时候,经常会遇到一些 Rtools 的问题,今天聊一下. Rtools 是什么 Rtools 作用很大,但我们一般不怎么会直接使用. Rtools p ...

  2. 通过redis学网络(1)-用go基于epoll实现最简单网络通信框架

    本系列主要是为了对redis的网络模型进行学习,我会用golang实现一个reactor网络模型,并实现对redis协议的解析. 系列源码已经上传github https://github.com/H ...

  3. App性能测试之iTest

    本文主要介绍下App性能测试工具iTest_V4.7的使用. 功能简介 1.监控Andorid系统(支持手机,平板,电视,车机等智能终端设备)以及应用app的cpu.内存.流量.电池.帧率.页面耗时等 ...

  4. 带你体验AI系列之云原生最佳实践--免费体验GPT-4教程

    前言 ​ [GPT-4]是OpenAI最新推出的大型语言模型,它支持图像和文本输入,以文本形式输出.它比GPT-3.5更大.更强.更猛.最重要的是据与研究表明,他在某些场景下,可以通过图灵测试.但是, ...

  5. h2database BTree 设计实现与查询优化思考

    h2database 是使用Java 编写的开源数据库,兼容ANSI-SQL89. 即实现了常规基于 BTree 的存储引擎,又支持日志结构存储引擎.功能非常丰富(死锁检测机制.事务特性.MVCC.运 ...

  6. GO web学习(一)

    跟着b站https://space.bilibili.com/361469957 杨旭老师学习做的笔记 开启web服务 •http.ListenAndServer() •第一个参数是网络地址 如果为& ...

  7. 基于JavaFX的扫雷游戏实现(三)——交互逻辑

      相信阅读过上期文章,动手能力强的朋友们已经自己跑出来界面了.所以这期我要讲的是交互部分,也就是对于鼠标点击事件的响应,包括计时计数对点击事件以及一些状态量的影响.   回忆下第一期介绍的扫雷规则和 ...

  8. 【项目学习】ERC-4337 抽象账户项目审计过程中需要注意的安全问题

    抽象账户是什么 抽象账户(也有叫合约钱包)是 EIP-4337 提案提出的一个标准.简单来说就是通过智能合约来实现一个"账户(account)",在合约中自行实现签名验证的逻辑.这 ...

  9. MySQL到ClickHouse数据同步方案

    MySQL 同步到 ClickHouse的方案可以看下面的说明,选择合适最近的同步方法. 1. 对比结果概述 整体上,NineData(官网:www.ninedata.cloud )的数据复制功能在功 ...

  10. Object.equals 和 String.equals的区别

    一.  源码展示: 1. Object.equals: ①引用类型地址值比较,直接返回结果:true || false public class Object { public boolean equ ...