博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[CF1534F1/2]Falling Sand
阅读量:4184 次
发布时间:2019-05-26

本文共 3259 字,大约阅读时间需要 10 分钟。

题解

About F1

首先我们应该很容易想到建图。

对于一个沙子,向它左,右,上,下四个方向能影响到的最近的沙子连边,很明显,通过这些方块总存在一条到其它能影响到的沙子。
我们要找的,就是选择尽量少的沙子使得它将所有点都覆盖到。
但这连出来的图是存在环的,环内的沙子是会互相影响的。
这是我们就需要缩点了,缩点后得到的无环有向图,选择所有入度为零的沙子即可。
时间复杂度 O ( n m ) O\left(nm\right) O(nm)

About F2

对于这个图,我们只需要让第 i i i列的第 a i a_{i} ai块掉下来即可,它们掉了,下面的自然也会掉。

我们还是先建图,跑tarjan缩点。
但对于包含第 i i i列第 a i a_{i} ai个的,我们称其为关键点。我们的目的就是让所有的关键点都掉下去。
对于可以被其它关键点走到的关键点,是没有意义的,我们可以不管它们。

之后我们可以发现,对于任何一个点,它能够走到的关键点的区间是连续的。

如果存在 i < j < k i<j<k i<j<k使得 i i i列与 k k k列的对应的关键点能被走到,但 j j j列不能。那么 i i i列与 k k k列一定可以通过 j j j列中的一个点联通。
如果这个点在 j j j列的关键点之下,那么 j j j列的关键点必然可以影响到 i i i列与 k k k列中的一个关键点。
如果这个点在 j j j列的关键点之上,那么 j j j列的关键点必然可以被 i i i列或 k k k列中的一个关键点影响到。
无论怎么都不满足我们的条件,所以其对应的区间必定是连续的。

所以我们可以先通过拓扑求出每个点对应的区间,然后将所有的区间按左端点排序,贪心选出最少的区间使其覆盖所有关键点即可。

时间复杂度 O ( n m l o g   n m ) O\left(nmlog\,nm\right) O(nmlognm)

源码

#include
using namespace std;#define MAXN 400005#define lowbit(x) (x&-x)#define reg register#define mkpr make_pairtypedef long long LL;typedef unsigned long long uLL;const int INF=0x3f3f3f3f;const int mo=1e9+7;const int iv2=5e8+4;const int lim=1000000;const int jzm=2333;const int orG=3,invG=332748118;const double Pi=acos(-1.0);typedef pair
pii;const double PI=acos(-1.0);template
_T Fabs(_T x){
return x<0?-x:x;}template
void read(_T &x){
_T f=1;x=0;char s=getchar(); while(s>'9'||s<'0'){
if(s=='-')f=-1;s=getchar();} while('0'<=s&&s<='9'){
x=(x<<3)+(x<<1)+(s^48);s=getchar();} x*=f;}template
void print(_T x){
if(x<0){
x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}int gcd(int a,int b){
return !b?a:gcd(b,a%b);}int add(int x,int y){
return x+y
s[MAXN],Id[MAXN],G[MAXN];queue
q;struct edge{ int to,nxt;}e[MAXN<<2];struct range{ int l,r;}sd[MAXN];inline void addEdge(int u,int v){ e[++tot]=(edge){ v,head[u]};head[u]=tot;}bool cmp(range x,range y){ return x.l
0;i--) for(reg int j=0;j<(int)G[ord[i]].size();j++) sd[ord[i]].l=min(sd[ord[i]].l,sd[G[ord[i]][j]].l), sd[ord[i]].r=max(sd[ord[i]].r,sd[G[ord[i]][j]].r);}signed main(){ read(n);read(m); for(reg int i=1;i<=n;i++){ scanf("%s",maze+1); for(reg int j=1;j<=m;j++)if(maze[j]=='#') s[j].push_back(i),Id[j].push_back(++cnt); } for(reg int i=1;i<=m;i++)read(a[i]); for(reg int i=1;i<=m;i++) for(reg int j=0;j<(int)s[i].size();j++){ if(!s[i-1].empty()&&s[i][j]<=s[i-1][s[i-1].size()-1]){ int l=0,r=s[i-1].size()-1; while(l
>1;if(s[i-1][mid]>=s[i][j])r=mid;else l=mid+1;} addEdge(Id[i][j],Id[i-1][l]); } if(!s[i+1].empty()&&s[i][j]<=s[i+1][s[i+1].size()-1]){ int l=0,r=s[i+1].size()-1; while(l
>1;if(s[i+1][mid]>=s[i][j])r=mid;else l=mid+1;} addEdge(Id[i][j],Id[i+1][l]); } if(j<(int)s[i].size()-1)addEdge(Id[i][j],Id[i][j+1]); if(j>0&&s[i][j-1]+1==s[i][j])addEdge(Id[i][j],Id[i][j-1]); } for(reg int i=1;i<=cnt;i++)if(!dfn[i])tarjan(i); for(reg int i=1;i<=m;i++){ int t=s[i].size()-a[i]; if(0<=t&&t<(int)s[i].size()) p[i]=belong[Id[i][t]],key[p[i]]=1; } for(reg int i=1;i<=cnt;i++) for(reg int j=head[i];j;j=e[j].nxt)if(belong[i]!=belong[e[j].to]) G[belong[i]].push_back(belong[e[j].to]),deg[belong[e[j].to]]++; sakura();num++;sd[num].l=sd[num].r=m+2;sort(sd+1,sd+num+1,cmp);int ans=0,R=0,L=0; for(reg int i=1;i<=num&&sd[i].l<=m;i++){ while(L
L+1&&L

谢谢!!!

转载地址:http://teyoi.baihongyu.com/

你可能感兴趣的文章
solr中文分词的种类
查看>>
solr作为一种开源的搜索服务器
查看>>
solr检索建议的功能
查看>>
solr4.3的入门配置
查看>>
mmseg4j在solr4.3里面的配置
查看>>
初识Solr
查看>>
solr高亮功能
查看>>
solrcloud的分布式集群方案
查看>>
solr搭建一个基于eclipse的源码环境
查看>>
GreenPlum的并行查询优化策略
查看>>
mondrian和ssas哪个好
查看>>
Solr作为一个Web应用,可以部署在多种应用服务器
查看>>
Directory家族的层级分布图
查看>>
我们为什么应该坚持写博客
查看>>
因为多个jar可能记录日志信息时,日志模块,不知道需要用那个jar包
查看>>
Lucene里面支持join操作
查看>>
solr 4.2的入门配置
查看>>
shell脚本一键安装solr
查看>>
solr原子更新功能
查看>>
greenplum + pgsql和Hadoop+hive+hbase
查看>>