前面的水题,在队友的配合下,很快就拿下了,剩下几道大毒瘤题,一直罚座三个小时,好让人自闭...但不得不说,这些题的质量是真的高!

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部分题题解的更多相关文章

  1. 2020 ICPC Universidad Nacional de Colombia Programming Contest

    2020 ICPC Universidad Nacional de Colombia Programming Contest A. Approach 三分 显然答案可以三分,注意\(eps\)还有两条 ...

  2. 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...

  3. 2021ICPC网络赛第一场部分题解-The 2021 ICPC Asia Regionals Online Contest (I)

    写在前面 本来应该6题的,结果不知道哪个铸币发了H的clar,当即把我们的思路转向三维几何上.当时我们还在想这三维计算几何的正确率有点太高了还在感叹ICPC选手的含金量,直到赛后我才知道这H题的铸币出 ...

  4. 2019 ICPC Universidad Nacional de Colombia Programming Contest C D J

    C. Common Subsequence 题意:给出长度为n两个串,求两个串的最长公共子序列len,如果len>=0.99*n,两个串就是亲兄弟否则不是. 解法:朴素的求LCS的时间复杂度是O ...

  5. 2021 ICPC 江西省赛总结

      比赛链接:https://ac.nowcoder.com/acm/contest/21592   大三的第一场正式赛,之前的几次网络赛和选拔赛都有雄哥坐镇,所以并没有觉得很慌毕竟校排只取每个学校成 ...

  6. 【2021 ICPC Asia Jinan 区域赛】 C Optimal Strategy推公式-组合数-逆元快速幂

    题目链接 题目详情 (pintia.cn) 题目 题意 有n个物品在他们面前,编号从1自n.两人轮流移走物品.在移动中,玩家选择未被拿走的物品并将其拿走.当所有物品被拿走时,游戏就结束了.任何一个玩家 ...

  7. IMO 2021 第一题题解及相关拓展问题分析

    IMO 2021 第 1 题: 设整数 n ≥ 100.伊凡把 n, n + 1, ..., 2n 的每个数写在不同的卡片上.然后他将这 n + 1 张卡片打乱顺序并分成两堆.证明:至少有一堆中包含两 ...

  8. [刷题]ACM/ICPC 2016北京赛站网络赛 第1题 第3题

    第一次玩ACM...有点小紧张小兴奋.这题目好难啊,只是网赛就这么难...只把最简单的两题做出来了. 题目1: 代码: //#define _ACM_ #include<iostream> ...

  9. 2017 ICPC区域赛(西安站)--- J题 LOL(DP)

    题目链接 problem description 5 friends play LOL together . Every one should BAN one character and PICK o ...

随机推荐

  1. C++ windows 函数讲解(一)获得屏幕分辨率

    先上代码: #include<bits/stdc++.h> #include<windows.h> using namespace std; int main() { int ...

  2. 使用 VSCode 开发调试 STM32 单片机尝试

    使用 VSCode 开发调试 STM32 单片机尝试 本文记录基于 Windows + DAP-Link 开发 STM32F103C8T6 的实践过程,其他操作系统或芯片应该也只是大同小异的问题. 注 ...

  3. 前端常用场景总结CSS/JS/插件(实用篇更新中...)

    <div class="box box1"> <span>垂直居中</span> </div> .box1{ display: ta ...

  4. Shell系列(22)- 字符截取命令awk

    简介 awk是一个数据处理工具,相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分成数个"字段"来处理 awk的流程是依次读取每一行数据,读取完一行数据后,进行条件判断 ...

  5. javascript/html 禁止图片缓存

    更新图片, 如果图片的url没有改变, 刷新页面之后图片会使用缓存的图片 Solutions: * js改变图片链接 (添加get参数) // 假设当前这个图片的dom对象为img img.src + ...

  6. three.js 纹理动画实现

    需求: 1.使用一张长图.分别播放这张长图的不同位置 来达到动态内容的目的 解决方案: 1.纹理创建并指定重复方向:this.texture.wrapS = this.texture.wrapT = ...

  7. 这是我见过最简单的博客文只有一张图,Python基础10分钟学完

  8. JS 实现计算器功能

    括号功能未实现,后续更 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  9. k8s学习笔记(1)- 简单部署springboot应用

    前言:k8s全称kubernetes,k8s是为容器服务而生的一个可移植容器的编排管理工具,越来越多的公司正在拥抱k8s,并且当前k8s已经主导了云业务流程,关于更多的k8s知识,可自行学习 1.k8 ...

  10. 图解java 多线程模式 读书笔记

    第1章"Single Threaded Execution模式--能通过这座桥的只有一个人" 该模式可以确保执行处理的线程只能是一个,这样就可以有效防止实例不一致. 第⒉章&quo ...