2021 ICPC Gran Premio de Mexico 2da Fecha部分题题解
前面的水题,在队友的配合下,很快就拿下了,剩下几道大毒瘤题,一直罚座三个小时,好让人自闭...但不得不说,这些题的质量是真的高!
H. Haunted House
首先看这个题,大眼一扫,觉得是某种数据结构的题,之后就把思考的重心放在了如何快速判断某个人会在哪个屋子遇到鬼上,由于鬼的活跃期会不定时的更新(指的是当一个鬼吓到一个人之后就会立即休眠,它的周期也会随即发生变化),发现这个东西真的很难维护,让人找鬼感觉做不了。...害,思路一旦僵住之后,路就走窄了...其实我们可以再看看这个题的数据范围,因为一个题的数据范围的特性往往会提示本题的解决方法。我们发现一个事情,首先每个鬼的精力是一个排列,如果按照我们刚才的想法,完全没有这个必要啊。还有发现人进来的时刻\(t\leq10^5\),为什么这个时间也给得这么小,如果在最后的算法和时间t没关系的话,大可以给个\(1e9\)啊。所以这个时候,我们就可以尝试转换下思路。维护鬼的状态,有点多,不妨我们维护人,让鬼去抓人。人的信息很简单就是进来的时间,我们对鬼进行操作。这个时候就要思考怎么让鬼抓人,如果我们总的去枚举时间的话,那么同一时刻会有多个人同时进入不同的屋子,这个貌似也很难搞。相比较于人一个一个的进入,我们不妨将所有人一起进入,只是他们的时间不同了。也就是说之前我们的想法就是他们一个一个的走全部的屋子,现在我们要让他们一起走第一个屋子,一起走第二个屋子,...这样的话,对于鬼的状态我们就能很轻松的维护。他们一起走,第一个鬼拦住一部分人,第二个鬼拦住一部分人,...直到最后一个鬼。思考发现这和题意是等价的。我们枚举每个鬼的活跃期,进行阻拦,然后,如果有人在其活跃期内,则直接更新该鬼的状态。发现每个鬼的活跃期的个数为\(\frac{m}{x}\),m表示我们枚举总的时间,注意x是个排列,那么这里的复杂度就为\(mlogm\),这里的m为总的时间,m取2e,用set再方便不过了,总的复杂度就为\(MlogMlogN\).
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,p[N],t[N],ro[N],ts[N];
set<pair<int,int> >st;
int main()
{
// freopen("1.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i) scanf("%d",&p[i]);
for(int i=0;i<m;++i)
{
scanf("%d",&t[i]);
st.insert({t[i],i});
}
for(int i=0;i<n;++i)//哪个人会被第i个鬼吓到
{
int cur=0;//记录当前鬼开始活跃的时间,最初是从0开始活跃的。
while(true)//不断枚举鬼的活跃的时间,阻拦人。
{
auto it=st.lower_bound({cur-i,-1});//人走i秒到当前屋子,相当于鬼的活跃-i。
if(it==st.end()) break;//鬼开始活跃的时间超出了所有人到达的时间。直接退出。
pair<int,int>x=*it;
if(x.first<=cur+p[i]-1-i)//x到达时,鬼还在活跃期内。 当前这个人被鬼吓。
{
st.erase(it);//从人群中剔除。
ro[x.second]=i;
ts[x.second]=x.first+i;
cur=x.first+i+p[i]+1;
}
else//鬼在这个活跃期内没有吓到人。
{
cur+=2*p[i];
}
}
}
for(auto x:st) ro[x.second]=ts[x.second]=-1;
for(int i=0;i<m;++i) printf("%d %d\n",ro[i],ts[i]);
return 0;
}
A. Alice Birthday
这个题的题意也是很简单的,给你一个无向图,每个边都可以删或不删,问最后的连通块为i的方案数,都输出出来?(\(1\leq i\leq n\))
首先观察题目的数据范围,N最大是14,这铁定状压(啥,你说爆搜,这档次的题应该不会考吧...)
接下来的问题是怎么状压,由于本题和连通块的个数有关,并且要用到状压,我们可以想到用f[s][j]表示状态s下,连通块的个数为j的方案数。考虑怎么转移。这个题真的加深了我对DP的理解,每个状态的实质就是一堆有某个共同性质的集合。我们转移时可以考虑根据某个规则,将该集合内的所有状态分成不同的组,这样就实现了状态的转移。比如说这个题,我们对集合S而言,我们只考虑编号最小的点所在的连通块,于是我们按照编号最小的点所在的不同连通块的集合为规则,划分这个集合。思考:当前集合的任何一个合法的状态都是可以根据编号最小的点进行枚举的,且不重复,我们设t为s的子集且t包含了s中编号最小的点,那么\(f[s][j]=\sum f[s异或t][j-1]*g[t]\);其中\(g[t]\)表示当前状态为t时,为一个连通块的方案数。考虑这个怎么搞,正难则反,我们考虑当前状态下,不连通的方案数,同样的我们考虑编号最小的点所在的连通块,肯定的是这个连通块,肯定没有和其他的点全部联通,我们考虑枚举所有的子集t且包含编号最小的点,我们可以是这个连通块联通,剩下的点之间的边都可选可不选,还是按照编号最小的点所在的连通块的状态来分组。至于所有状态枚举子集的复杂度为\(O(3^n)\)此题,我怀疑14就是这么来的。...
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=20010,P=998244353;
int n,m,a[21][21],xp[N];
ll f[N][21],g[N],has[N];
int main()
{
// freopen("1.in","r",stdin);
scanf("%d%d",&n,&m);
xp[0]=1;
for(int i=1;i<=m;++i) xp[i]=xp[i-1]*2%P;
for(int i=1;i<=m;++i)
{
int x,y;
scanf("%d%d",&x,&y);
x--;y--;
a[x][y]=a[y][x]=1;
}
for(int S=1;S<(1<<n);++S)//处理g[S].
{
for(int j=0;j<n;++j) if(S&(1<<j))
for(int k=j+1;k<n;++k) if(S&(1<<k))
{
if(a[j][k]) has[S]++;
}
g[S]=xp[has[S]];//先算出总的方案数。
int u=S&(-S);
for(int t=(S-1)&S;t;t=(t-1)&S)
{
if(t&u)//必须包含编号最小的点。
{
g[S]=(g[S]-g[t]*xp[has[S^t]])%P;
g[S]=((g[S]+P)%P+P)%P;
}
}
}
for(int S=1;S<(1<<n);++S)
{
for(int j=1;j<=n;++j)
{
if(j==1) f[S][j]=g[S];
else
{
int u=S&(-S);
for(int t=(S-1)&S;t;t=(t-1)&S)
{
if(t&u)//必须包含编号最小的点。
{
f[S][j]=(f[S][j]+f[S^t][j-1]*g[t])%P;
}
}
}
}
}
for(int i=1;i<=n;++i) printf("%lld\n",f[(1<<n)-1][i]);
return 0;
}
2021 ICPC Gran Premio de Mexico 2da Fecha部分题题解的更多相关文章
- 2020 ICPC Universidad Nacional de Colombia Programming Contest
2020 ICPC Universidad Nacional de Colombia Programming Contest A. Approach 三分 显然答案可以三分,注意\(eps\)还有两条 ...
- 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...
- 2021ICPC网络赛第一场部分题解-The 2021 ICPC Asia Regionals Online Contest (I)
写在前面 本来应该6题的,结果不知道哪个铸币发了H的clar,当即把我们的思路转向三维几何上.当时我们还在想这三维计算几何的正确率有点太高了还在感叹ICPC选手的含金量,直到赛后我才知道这H题的铸币出 ...
- 2019 ICPC Universidad Nacional de Colombia Programming Contest C D J
C. Common Subsequence 题意:给出长度为n两个串,求两个串的最长公共子序列len,如果len>=0.99*n,两个串就是亲兄弟否则不是. 解法:朴素的求LCS的时间复杂度是O ...
- 2021 ICPC 江西省赛总结
比赛链接:https://ac.nowcoder.com/acm/contest/21592 大三的第一场正式赛,之前的几次网络赛和选拔赛都有雄哥坐镇,所以并没有觉得很慌毕竟校排只取每个学校成 ...
- 【2021 ICPC Asia Jinan 区域赛】 C Optimal Strategy推公式-组合数-逆元快速幂
题目链接 题目详情 (pintia.cn) 题目 题意 有n个物品在他们面前,编号从1自n.两人轮流移走物品.在移动中,玩家选择未被拿走的物品并将其拿走.当所有物品被拿走时,游戏就结束了.任何一个玩家 ...
- IMO 2021 第一题题解及相关拓展问题分析
IMO 2021 第 1 题: 设整数 n ≥ 100.伊凡把 n, n + 1, ..., 2n 的每个数写在不同的卡片上.然后他将这 n + 1 张卡片打乱顺序并分成两堆.证明:至少有一堆中包含两 ...
- [刷题]ACM/ICPC 2016北京赛站网络赛 第1题 第3题
第一次玩ACM...有点小紧张小兴奋.这题目好难啊,只是网赛就这么难...只把最简单的两题做出来了. 题目1: 代码: //#define _ACM_ #include<iostream> ...
- 2017 ICPC区域赛(西安站)--- J题 LOL(DP)
题目链接 problem description 5 friends play LOL together . Every one should BAN one character and PICK o ...
随机推荐
- 如何获取PHP命令行参数
使用 PHP 开发的同学多少都会接触过 CLI 命令行.经常会有一些定时任务或者一些脚本直接使用命令行处理会更加的方便,有些时候我们会需要像网页的 GET . POST 一样为这些命令行脚本提供参数. ...
- 数据库删除discuz 部分数据操作
如何快速清理discuz 3.2 中等待审核的回复数:pre_forum_post_moderate,点击清空 清空回收站的主题帖:DELETE FROM `pre_forum_thread` WHE ...
- maven编译打包
sonar扫描java项目,需要使用maven 来到maven项目下第一件事情编译打包,注意代码扫描是在编译之后的:https://blog.csdn.net/qq_34556414/article/ ...
- cgroup之cpu关键参数
cpu.cfs_period_us specifies a period of time in microseconds (µs, represented here as "us" ...
- [C语言]学习之路
实例:C语言编程题 求100到300之间所有素数 #include <stdio.h> int main(void) { int i,j; for(i = 100;i <= 300; ...
- Redis之品鉴之旅(五)
Redis事务 原子性:就是最小的单位 一致性:好多命令,要么全部执行成功,要么全部执行失败 隔离性:一个会话和另一个会话之间是互相隔离的 持久性:执行了就执行了,数据保存在硬盘上 典型例子:银行转账 ...
- 腾讯首个CNCF沙箱开源项目
作者 SuperEdge开发者.腾讯云容器产品中心边缘计算团队.腾讯开源生态管理协会 SuperEdge 进入 CNCF 沙箱 2021 年 9 月 14 日,云原生分布式边缘容器系统 SuperEd ...
- 实验1:SDN拓扑实践
作业链接:实验1:SDN拓扑实践 一.实验目的 能够使用源码安装Mininet: 能够使用Mininet的可视化工具生成拓扑: 能够使用Mininet的命令行生成特定拓扑: 能够使用Mininet交互 ...
- 《手把手教你》系列技巧篇(三十)-java+ selenium自动化测试- Actions的相关操作下篇(详解教程)
1.简介 本文主要介绍两个在测试过程中可能会用到的功能:Actions类中的拖拽操作和Actions类中的划取字段操作.例如:需要在一堆log字符中随机划取一段文字,然后右键选择摘取功能. 2.拖拽操 ...
- .Net Core 获取上下文HttpContext
1.先定义一个类 using Microsoft.AspNetCore.Http; namespace BCode.Util { public class MvcContext { public st ...