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

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. PTA 面向对象程序设计 6-1 引用作函数形参交换两个整数

    引用作函数形参交换两个整数 设计一个void类型的函数Swap,该函数有两个引用类型的参数,函数功能为实现两个整数交换的操作. 裁判测试程序样例: #include <iostream> ...

  2. 无序数组求第K大的数

    问题描述 无序数组求第K大的数,其中K从1开始算. 例如:[0,3,1,8,5,2]这个数组,第2大的数是5 OJ可参考:LeetCode_0215_KthLargestElementInAnArra ...

  3. 一文让你彻底搞懂 vue-Router

    路由是网络工程里面的专业术语,就是通过互联把信息从源地址传输到目的地址的活动.本质上就是一种对应关系.分为前端路由和后端路由. 后端路由: URL 的请求地址与服务器上的资源对应,根据不同的请求地址返 ...

  4. Sentry 监控 - Security Policy 安全策略报告

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  5. 第三方api接口

    做为一个软件测试工程师,你要学习接口测试,需要练习,那么就要有调用的api,可以参考以下的文章. 国内7款API供应平台功能对比及详细介绍 https://blog.csdn.net/ishxiao/ ...

  6. PHP 流行的框架

    Aura Laravel Symphony Yii Zend php components Packagist 最好的组件: Awesome PHP https://www.yiiframework. ...

  7. Fillder抓包配置

    Faillder设置,完成以下设置后重启Fillder Fillder工具配置 设置端口 端口设置 (根据公司限制使用范围内的端口) 设置是否远程连接 勾选Decrypt HTTPS traffic ...

  8. whistle抓包-数据包分析

    额,这篇忘了是来自哪位作者的了. whistle:1.14.6 这里以抓取浏览器数据包为例,分析抓取的数据. Method:Connect,对应Host:Tunnel to意思是因为网络环境受限,客户 ...

  9. 字体小于12px 无法缩小解决方案

    通过缩放进行大小控制. 缩放可能会导致元素也进行缩放.需要注意 transform: scale(0.5);

  10. Kronecker product

    Kronecker product 的基本运算 结合律 \begin{equation} \mathrm{A} \otimes (\mathrm{B + C}) = \mathrm{A} \otime ...