考场

终于有一场在晚上考了

T1 随便画了画就发现要求每个点的后继个数,想起来有 dfs 和 toposort 两种方法,感觉很稳

T2 裸的网络流有 70pts?!真香

一看 T3 就想起了 Mst,随便建个 MST 然后枚举非树边在树上搞搞就行了,画了画图发现可行(但心里对这个算法对正确性并不太肯定)。在树剖+线段树和 LCT 之间选择了 LCT,毕竟刚背了 LCT少个 \(\log\)

感觉这次题都比较可做,暴力分也很多,rk1 可能要 250+,决定冲 T3 的数据结构

19.00 就开始写了,绝望的发现 T1 不会做,先写了暴力 bitset,发现极限数据也跑得挺快,就是会 MLE。尝试 dfs 出一颗生成树,然后树上差分,画了画图发现不行。不管了

T2 飞快写完 ISAP,一遍过样例。部分分太香+着急写 T3 就没多想。又回头看 T1,仔细回想 受欢迎的牛 和 bitset 水过去的 连通数,悔不当初。(当时以为有 \(O(n)\) 在 DAG 上 DP 的方法)

19.40 终于开始写 T3,先后经历了 CE WA RE,20.50 过样例,想了想还是写了对拍,但只是把树上更新的部分换成了暴力跳 fa,只能拍出 LCT 有没有写挂,算法正确性无法保证(不会写其他暴力)。结果从 9.10 开始拍,LCT 和暴力轮流挂,直到快 9.30 才稳定拍上,最终只拍了一百多组。此时发现 T1 还有图退化成树的 20pts 没写,Rush 了 10min 写完了,在结束前 40s 提交。

ycx 说听到我一直在敲键盘。。。今天默板子是真爽

res

rk1 40+60+100

T1 树的分还是没拿到(默认了根是 \(1\))

T2 挂了第 1 个点(由于存边的数组开了 \(N*N\),因此 \(N\) 没敢开大,而第一个点恰好是 \(n=1,m=5\times10^4\))

rk3 ycx 60+70+30

rk4 贾一丰 40+100+0

世界线

正解就是 bitset。。。

防止被卡空间要开成 bitset<N/2> siz[N];,然后每次只在 bitset 中转移一半点。

code
const int N = 6e4+1;
int n,m;
vector<int> to[N]; int nn;
LL ans;
bool vis[N];
bitset<30001> siz[N]; void dfs(int u,bool op) {
if( vis[u] ) return;
vis[u] = 1;
if( !op && u <= nn ) siz[u][u] = 1;
else if( op && u > nn ) siz[u][u-nn] = 1;
for(int v : to[u]) {
dfs(v,op);
siz[u] |= siz[v];
}
} signed main() {
read(n,m); nn = n/2;
For(i,1,m) {
int x,y; read(x,y);
to[x].pb(y);
}
For(i,1,n) dfs(i,0);
For(i,1,n) ans += siz[i].count(), siz[i].reset();
mem(vis,0,n);
For(i,1,n) dfs(i,1);
For(i,1,n) ans += siz[i].count();
write(ans-n-m);
return ioclear();
}

时间机器

贪心。

按 \(low\) 从小到大考虑每个结点,每次在 \(l\le low\) 的电阻中匹配 \(high\le r\) 且 \(r\) 最小的,暴力是 \(O(nm)\) 的,可以用 set 或权值线段树优化这个查找的过程。

显然 set 中可能有重复元素,要开 multiset,但实测不开可过。hack:

Input:

1
2 2
1 2 1
1 2 1
1 2 1
1 2 1 Output: Yes
code
const int N = 5e4+5;
int T,n,m;
struct Node {
int l,r,n;
} a[N],b[N];
bool operator < (const Node &x,const Node &y) { return x.l < y.l; } struct Rest {
int r;
mutable int n;
Rest(int r=0,int n=0):r(r),n(n){}
};
bool operator < (const Rest &x,const Rest &y)
{ return x.r!=y.r ? x.r<y.r : x.n<y.n; }
multiset<Rest> s; void solve() {
read(n,m);
For(i,1,n) read(a[i].l,a[i].r,a[i].n);
For(i,1,m) read(b[i].l,b[i].r,b[i].n);
sort(a+1,a+n+1), sort(b+1,b+m+1);
for(int i = 1, j = 1; i <= n; ++i) {
for(; j <= m && b[j].l <= a[i].l; ++j) s.insert(Rest(b[j].r,b[j].n));
while( a[i].n ) {
auto it = s.lower_bound(Rest(a[i].r,0));
if( it == s.end() ) { puts("No"); return; }
if( it->n > a[i].n ) { it->n -= a[i].n; break; }
a[i].n -= it->n, s.erase(it);
}
}
puts("Yes");
} signed main() {
read(T);
while( T-- ) {
s.clear();
solve();
}
return 0;
}

weight

正确性:断开一条树边后形成两个连通块,考虑连接这两个连通块的边何时一定比其它边优

我的 LCT 常数爆炸,被树剖+线段树吊打。。。

考场 code
const int N = 7e4+5, M = 1e5+5, inf = 0x7fffffff;
int n,m,Type;
struct Edge {
int u,v,w,id;
} e[M]; int fa[N],ans[M];
bool vis[M]; int find(int x) { return fa[x]==x ? x : fa[x]=find(fa[x]); } #define ls(x) t[x].ch[0]
#define rs(x) t[x].ch[1]
struct Node {
int fa,ch[2],val,mx,ans,tag;
bool rev;
} t[N+M];
class LCT {
private:
bool nrt(int u) { return ls(t[u].fa)==u || rs(t[u].fa)==u; }
void up(int u) { t[u].mx = max(max(t[ls(u)].mx,t[rs(u)].mx),t[u].val); }
void rev(int u) { swap(ls(u),rs(u)), t[u].rev ^= 1; }
void down(int u,int x)
{ t[u].ans = min(t[u].ans,x), t[u].tag = min(t[u].tag,x); }
void down(int u) {
if( t[u].rev ) {
rev(ls(u)), rev(rs(u));
t[u].rev = 0;
}
down(ls(u),t[u].tag), down(rs(u),t[u].tag), t[u].tag = inf;
}
bool which(int u) { return rs(t[u].fa) == u; }
void rotate(int x) {
int y = t[x].fa, z = t[y].fa, k = which(x), w = t[x].ch[!k];
if( nrt(y) ) t[z].ch[which(y)] = x;
t[y].ch[k] = w, t[x].ch[!k] = y;
if( w ) t[w].fa = y;
t[y].fa = x, t[x].fa = z;
up(y);
}
void splay(int u) {
static int stk[N+M];
int tp = 1, v = stk[1] = u;
while( nrt(v) ) stk[++tp] = v = t[v].fa;
while( tp ) down(stk[tp--]);
for(int fa; fa = t[u].fa, nrt(u); rotate(u))
if( nrt(fa) ) rotate(which(u)==which(fa)?fa:u);
up(u);
}
void access(int x) {
for(int u = x, v = 0; u; u = t[ v=u ].fa)
splay(u), rs(u) = v, up(u);
splay(x);
}
public:
void makert(int u) { access(u), rev(u); }
int findrt(int u) {
access(u);
while( ls(u) ) down(u), u = ls(u);
splay(u);
return u;
}
void link(int u,int v) { makert(u), splay(v), t[u].fa = v; }
void split(int u,int v) { makert(u), access(v); }
} lct; signed main() {
// freopen("c.in","r",stdin);
// freopen("c.out","w",stdout);
read(n,m,Type);
For(i,1,n) fa[i] = i;
For(i,1,m) {
read(e[i].u,e[i].v,e[i].w), e[i].id = i;
fa[find(e[i].u)] = find(e[i].v);
}
sort(e+1,e+m+1,[](const Edge &x,const Edge &y){return x.w<y.w;});
t[0].mx = -inf;
For(i,1,n+m) t[i].val = -inf, t[i].tag = inf;
For(i,1,m) if( find(e[i].u) == find(1) ) {
if( lct.findrt(e[i].u) == lct.findrt(e[i].v) ) continue;
vis[i] = 1;
t[n+i].val = e[i].w, t[n+i].ans = inf;
lct.link(e[i].u,n+i), lct.link(e[i].v,n+i);
}
For(i,1,m) {
int u = e[i].u, v = e[i].v;
if( find(u) != find(1) || vis[i] ) continue;
lct.split(u,v);
ans[e[i].id] = t[v].mx-1, t[v].tag = e[i].w-1;
}
For(i,1,m) if( vis[i] ) lct.makert(n+i), ans[e[i].id] = t[n+i].ans;
For(i,1,m) write(ans[i]==inf ? -1 : ans[i], ' ');
return ioclear();
}

考场上写挂的地方:

nrt(u) 判断 u 是否是 splay 的根

access 时先 splay

findrt 时先 access

操作完记得 splay

存答案的数组要开到边数

20210716 noip17的更多相关文章

  1. noip17

    复杂度分析全部摘自题解 T1 sb优化暴力 暴力20-40pts,我只拿了20pts. 正解: bitset 优化暴力,但是会MLE. 再次考虑如何优化,我们统计一下每个点的入度,每次遍历到这个点的时 ...

  2. 20210716考试-NOIP19

    u,v,w. 这场考过. T1 u 差分裸题 #include<bits/stdc++.h> using namespace std; const int N=5000; int n,m; ...

  3. 20210716考试-NOIP16

    考场时Prim的 $i$ 写成 $k$ 100->0 rank1->rank23 T1 Star Way To Heaven 考场正解:假设你要二分答案,则几个圆组成几道"屏障& ...

  4. 调用免费API查询全年工作日、周末、法定节假日、节假日调休补班数据

    前言 日常开发中,难免会用到判断今天是工作日.周末.法定节假日.节假日调休补班做一些业务处理,例如:仅在上班时间给用户推送消息.本文记录调用免费API查询全年工作日.周末.法定节假日.节假日调休补班数 ...

  5. Java 中节省 90% 时间的常用的工具类

    前言 你们有木有喜欢看代码的领导啊,我的领导就喜欢看我写的代码,有事没事就喜欢跟我探讨怎么写才最好,哈哈哈...挺好. 今天我们就一起来看看可以节省 90% 的加班时间的第三方开源库吧,第一个介绍的必 ...

  6. Java流程控制05——循环结构

    循环结构 while 循环  while(布尔表达式){   //循环语句 } 只要布尔表达式为true,循环就会一直执行下去. 我们为你大多数情况是会让循环停止下来的,我们需要让一个表达式时效的方式 ...

  7. Java流程控制04——Switch选择结构

    switch 多选择结构 switch case 语句判断一个变量与一系列值中某个值是否相等,每个支撑位一个分支. switch语句中的变量类型可以是: byte short int 或者 char ...

  8. Python小白的数学建模课-19.网络流优化问题

    流在生活中十分常见,例如交通系统中的人流.车流.物流,供水管网中的水流,金融系统中的现金流,网络中的信息流.网络流优化问题是基本的网络优化问题,应用非常广泛. 网络流优化问题最重要的指标是边的成本和容 ...

  9. centos7环境变量配置错误以至于命令不可使用

    2021-07-16 问题: centos7在配置环境变量的时候少打了$,导致很多命令不能使用 解决方法: 在命令行输入: export PATH=/usr/local/sbin:/usr/local ...

随机推荐

  1. azure删除ns时一直处于terminating状态

    写个脚本 #!/bin/bash NAMESPACE=corekubectl proxy &kubectl get namespace $NAMESPACE -o json |jq '.spe ...

  2. CC攻击和C2的区别

    [一]背景 今天被旁边姐姐问C2.CC是什么,虽然平时老看到这个词,身边也有自己写C2工具的大佬.但好像突然被问到有点懵,不知道怎么回答. [二]内容 CC ( Challenge Collapsar ...

  3. no-strings-attached writeup

    no-strings-attach writeup 1.程序分析 主函数如图所示,关键函数在authenticate中,进入函数. 分析可得,decrypt代码段为关键代码段,进入关键函数decryp ...

  4. 我一个五年Android开发,居然被一个技术不如我的面试官嫌弃了......

    背景 首先介绍一下自己的情况.目前所在的是一家小的创业公司,待了5年多,薪资一般吧.由于这几年公司也在转型.工作经历大概可以分为 3 个阶段. 第一阶段是从进公司开始做 android app 开发, ...

  5. java使用Selenium操作谷歌浏览器学习笔记(一)

    下载安装 在淘宝镜像https://npm.taobao.org/mirrors/chromedriver/中下载与浏览器对应的版本 查看浏览器版本 点击查看谷歌浏览器版本 在IDEA项目中导入相关j ...

  6. Salesforce Integration 概览(六) UI Update Based on Data Changes(UI自动更新基于数据变更)

    Salesforce用户界面必须由于Salesforce数据的更改而自动更新.这个场景其实在我所经历的项目中用到的不是特别多,因为客户可能直接点击刷新按钮就直接看到了最新的数据,而不是那种一直不刷新然 ...

  7. 【LeetCode】39. 组合总和

    39. 组合总和 知识点:递归:回溯:组合:剪枝 题目描述 给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数  ...

  8. flink clickhouse-jdbc和flink-connector 写入数据到clickhouse因为jar包冲突导致的60 seconds.Please check if the requested resources are available in the YARN cluster和Could not resolve ResourceManager address akka报错血案

    一.问题现象,使用flink on yarn 模式,写入数据到clickhouse,但是在yarn 集群充足的情况下一直报:Deployment took more than 60 seconds. ...

  9. 雪花算法ID在前端丢失精度解决方案

    首先说一下背景,目前笔者的工作是物联网方面的,设备有对应的智慧运营平台,平台开发中建表的主键用的是Mybatis plus默认的雪花算法来生成的,也就是分布式系统比较常用的雪花ID,技术栈就是常用的S ...

  10. 用Matlab求解微分方程

    用Matlab求解微分方程 解微分方程有两种解,一种是解析解,一种是数值解,这两种分别对应不同的解法 解析解 利用dsolve函数进行求解 syms x; s = dsolve('eq1,eq2,.. ...