2021.10.19 CSP 模拟赛 总结
T1
题意: \(n\) 个人摘苹果,跳起高度为 \(a_i\),苹果高度为 \(h_i\),高度小的先摘,摘了就没了
直接排序+双指针,复杂度 \(O(n+m)\)
T2
题意:要轰炸一个有向图的所有点,如果存在两个不同点 \(i\) 和 \(j\) ,并且 \(i\)、\(j\) 连通
那么 \(i\) 和 \(j\) 不能在同一次轰炸,问最少要多少次轰炸
tarjan 缩点 + 找最长路。考试时没有想到要最长路,缩点不是很会处理重边
复杂度 \(O(n+m)\)
#include<bits/stdc++.h>
using namespace std;
typedef long double LD;
typedef long long LL;
typedef double db;
const int N=1000005;
int n,m,sz[N],ans,rd[N],f[N],q[N],hd,tl;
int low[N],dfn[N],clk,s[N],top,cl[N],tot;
int lst1[N],nxt1[N],to1[N],cnt1;
int lst2[N],nxt2[N],to2[N],cnt2;
inline void Ae1(int fr,int go) { to1[++cnt1]=go,nxt1[cnt1]=lst1[fr],lst1[fr]=cnt1; }
inline void Ae2(int fr,int go) { to2[++cnt2]=go,nxt2[cnt2]=lst2[fr],lst2[fr]=cnt2; }
void tarjan(int u) {
dfn[u]=low[u]=++clk,s[++top]=u;
for(int i=lst1[u],v;i;i=nxt1[i]) {
if(!dfn[v=to1[i]]) {
tarjan(v);
low[u]=min(low[u],low[v]);
} else if(!cl[v]) {
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]) {
++tot,sz[tot]=1;
while(s[top]!=u)
++sz[tot],cl[s[top]]=tot,--top;
cl[u]=tot,--top;
}
}
int main() {
// freopen("bomb.in","r",stdin);
// freopen("bomb.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++) {
scanf("%d%d",&u,&v);
Ae1(u,v);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
for(int i=1;i<=n;i++)
for(int j=lst1[i];j;j=nxt1[j])
if(cl[i]!=cl[to1[j]])
Ae2(cl[i],cl[to1[j]]),++rd[cl[to1[j]]];
for(int i=1;i<=tot;i++)if(!rd[i])q[++tl]=i,f[i]=sz[i];
for(int u;hd<tl;) {
u=q[++hd],ans=max(ans,f[u]);
for(int i=lst2[u],v;i;i=nxt2[i]) {
--rd[v=to2[i]];
f[v]=max(f[v],f[u]+sz[v]);
if(!rd[v])q[++tl]=v;
}
}
printf("%d",ans);
}
T3
题意:一个无向图,一条路径长度是所有边权的最大值,两点距离是两点路径长度的最小值
操作 1 是加边,操作 2 是给 \(i,j,p,q\) ,算出 \(d1=dis(i,j),d2=dis(p,q)\) ,取出个数为 \(d1,d2\) 的两堆石子玩 \(\text{NIM}\) 博弈
然后问每次操作 2 谁赢
显然的 Kruskal + LCA ,查询距离解决
博弈的话直接异或即可
操作 1 个数 \(\le5000\)
所以直接暴力加边,重跑一遍生成树即可
复杂度 \(O(5000n+T\log n)\)
\(n\le5000\) ,卡过
#include<bits/stdc++.h>
using namespace std;
typedef long double LD;
typedef long long LL;
typedef double db;
const int N=5005,M=105005;
int n,m,T,ff[N],lst[N],nxt[N<<1],to[N<<1],cnt,dep[N],fa[N][15];
LL qz[N<<1],mx[N][15],Ra,Rb;
char op[5];
struct Ed { int u,v; LL w; }e[M];
inline bool cmp(Ed A,Ed B) { return A.w<B.w; }
int fd(int x) { return ff[x]==x?x:ff[x]=fd(ff[x]); }
inline void Ae(int fr,int go,LL vl) {
to[++cnt]=go,qz[cnt]=vl;
nxt[cnt]=lst[fr],lst[fr]=cnt;
}
void dfs(int u,int f) {
dep[u]=dep[f]+1,fa[u][0]=f;
for(int i=1;i<=13;i++) {
fa[u][i]=fa[fa[u][i-1]][i-1];
mx[u][i]=max(mx[u][i-1],mx[fa[u][i-1]][i-1]);
}
for(int i=lst[u],v;i;i=nxt[i])
if((v=to[i])^f)
mx[v][0]=qz[i],dfs(v,u);
}
inline void kru() {
cnt=1;
for(int i=1;i<=n;i++)
lst[i]=0,ff[i]=i,dep[i]=0;
for(int i=1,tt=0,p,q;i<=m;i++) {
p=fd(e[i].u),q=fd(e[i].v);
if(p==q)continue;
ff[q]=p,++tt;
Ae(e[i].u,e[i].v,e[i].w);
Ae(e[i].v,e[i].u,e[i].w);
if(tt==n-1)break;
}
dfs(1,1);
}
inline LL LCA(int x,int y) {
if(dep[x]<dep[y])x^=y^=x^=y;
register LL res=0;
for(int i=13;~i;i--)
if(dep[fa[x][i]]>=dep[y])
res=max(res,mx[x][i]),x=fa[x][i];
if(x==y)return res;
for(int i=13;~i;i--)
if(fa[x][i]!=fa[y][i]) {
res=max(res,max(mx[x][i],mx[y][i]));
x=fa[x][i],y=fa[y][i];
}
return max(res,max(mx[x][0],mx[y][0]));
}
int main() {
// freopen("game.in","r",stdin);
// freopen("game.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) {
scanf("%d%d%lld",&e[i].u,&e[i].v,&e[i].w);
}
sort(e+1,e+m+1,cmp);
kru();
scanf("%d",&T);
for(int a,b,c,d;T--;) {
scanf("%s",op);
if(op[0]=='a') {
++m;
scanf("%d%d%lld",&e[m].u,&e[m].v,&e[m].w);
for(int i=m;i>1;i--) {
if(cmp(e[i],e[i-1]))
swap(e[i],e[i-1]);
else break;
}
kru();
} else {
scanf("%d%d%d%d",&a,&b,&c,&d);
Ra=LCA(a,b);
Rb=LCA(c,d);
// printf("%lld %lld\n",Ra,Rb);
if(Ra!=Rb)puts("madoka");
else puts("Baozika");
}
}
}
T4
题意:一个序列的美观度 = 序列的数的和 / 序列被划分成的极长单调区间的个数(第一个区间必须单调递增)
求一个序列的所有子序列中美观度的最大值
重要性质:所选要么是一个单调上升序列,要么是一个上升序列和一个下降序列
因为这两个如果选出最大值,其他都是小的,只会让答案减小
就正着、反着分别求一次最大递增序列,然后取最大值即可
求的话直接离散化+树状数组
#include<bits/stdc++.h>
using namespace std;
typedef long double LD;
typedef long long LL;
typedef double db;
const int N=100005;
int n,m;
LL x[N],y[N],f[N],g[N],t[N];
db ans;
inline void mdy(int p,LL v) {
for(;p<=m;p+=p&-p)t[p]=max(t[p],v);
}
inline LL ask(int p) {
register LL res=0;
for(;p;p-=p&-p)res=max(res,t[p]);
return res;
}
int main() {
// freopen("seq.in","r",stdin);
// freopen("seq.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&x[i]),y[i]=x[i];
sort(y+1,y+n+1);
m=unique(y+1,y+n+1)-y-1;
y[++m]=1e9;
for(int i=1,v;i<=n;i++) {
v=lower_bound(y+1,y+m+1,x[i])-y;
f[i]=ask(v-1)+x[i];
mdy(v,f[i]);
}
memset(t,0,sizeof(t));
for(int i=n,v;i;i--) {
v=lower_bound(y+1,y+m+1,x[i])-y;
g[i]=ask(v-1)+x[i];
mdy(v,g[i]);
}
for(int i=1;i<=n;i++) {
ans=max(ans,1.0*f[i]);
ans=max(ans,1.0*(f[i]+g[i]-x[i])/2.0);
}
printf("%.3f",ans);
}
总结
- T1:**
- T2:第一次打 tarjan 缩点,以后要多角度思考缩完后的 DAG 如何求答案
- T3:告诉我们相信暴力能骗分
- T4:考虑答案最优性要满足什么条件
2021.10.19 CSP 模拟赛 总结的更多相关文章
- 10.17 NOIP模拟赛
目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...
- 10.16 NOIP模拟赛
目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...
- 10.30 NFLS-NOIP模拟赛 解题报告
总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...
- CSP模拟赛游记
时间:2019.10.5 考试时间:100分钟(连正式考试时间的一半还没有到)题目:由于某些原因不能公开. 由于第一次接触NOIinux系统所以连怎么建文件夹,调字体,如何编译都不知道,考试的前半小时 ...
- 2018.10.16 NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...
- 2019.10.26 CSP%您赛第三场
\(CSP\)凉心模拟^_^ --题源\(lqx.lhc\)等各位蒟蒻 题目名称 比赛 传递消息 开关灯 源文件名 \(competition.cpp\) \(message.cpp\) \(ligh ...
- 【CSP模拟赛】避难向导(倍增lca&树的直径)
耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...
- 【csp模拟赛6】相遇--LCA
对于30%的数据:暴力枚举判断 对于60%的数据:还是暴力枚举,把两条路径都走一遍计一下数就行,出现一个点被访问两次即可判定重合 对于100%的数据:找出每条路径中距离根最近的点(lca),判断这个点 ...
- 2019/11/12 CSP模拟赛&&考前小总结
写在前面的总结 离联赛只有几天了,也马上就要回归文化课了. 有点舍不得,感觉自己的水平刚刚有点起色,却又要被抓回文化课教室了,真想在机房再赖几天啊. 像19/11/11那场的简单题,自己还是能敲出一些 ...
随机推荐
- 引用nodejs的url模块实现url路由功能
我们在本地创建服务器之后需要写不同的后缀名来访问同一个站点的不同页面,如果不实现路由功能.则每次访问localhost:3000 不论后面写什么 比如localhost:3000/index.loc ...
- C语言---魔方阵
魔方阵的定义:在n*n的方阵中,每一行的和=每一列的和=对角线的和.(本文中涉及的n为大于3的奇数). 例如3*3的魔方阵为: 5*5的魔方阵为: 如何写魔方阵呢? 1.数字1位于第一行的正中间2.下 ...
- python---用顺序表实现双端队列
class Dqueue(object): """双端队列""" def __init__(self): self.__list = [] ...
- numpy---(上)
Numpy Numpy ndarray N维数组对象ndarray, 是一系列同类型数据的集合, 索引以0下标开始, 创建一个ndarray对象, 需调用array函数: numpy.array(ob ...
- Mybatis-Dao层实现(通过代理方式)
1.代理方式开发是主流 2.Mapper接口开发方法只需要编写Mapper接口(相当于Dao接口),然后由Mybatis根据接口创建动态代理对象 Mapper接口开发需要遵循以下规范 一一对应 Use ...
- java并发问题总结
1.java中产生并发问题的主要原因有哪三个? 原子性.可见性和有序性 2.什么是java内存模型? java虚拟机规范中用来屏蔽掉各种硬件和操作系统内存访问差异,java内存模型的主要目标是定义程序 ...
- 【面试普通人VS高手】Kafka的零拷贝原理?
最近一个学员去滴滴面试,在第二面的时候遇到了这个问题: "请你简单说一下Kafka的零拷贝原理" 然后那个学员努力在大脑里检索了很久,没有回答上来. 那么今天,我们基于这个问题来看 ...
- mmdetection 批量执行测试脚本
在终端执行该脚本,传入所有的测试路径,每一个model的结果文件夹里面有一个best文件夹存放着其训练时最高mAP对应的权重,名字为best.pth dir=$(ls -l $1 |awk '/^d/ ...
- IDEA SpringBoot-Mybatis-plus 实现增删改查(CRUD)
上一篇: IDEA SpringBoot-Mybatis实现增删改查(CRUD) 下一篇:Intellij IDEA 高效使用教程 (插件,实用技巧) 最好用的idea插件大全 一.前言 Mybati ...
- java中的stream是啥?
函数式编程的执行是惰性的,按顺序真正执行的时候才会执行相应的代码.方法: 函数式编程是安全的,用的是monad架构 1 public class StreamTest { 2 3 public sta ...