首页 > 其他分享 >CF1534F2 Falling Sand (Hard Version) 题解

CF1534F2 Falling Sand (Hard Version) 题解

时间:2024-09-08 17:51:39浏览次数:8  
标签:ch CF1534F2 题解 Hard && 沙子 关键点 col define

题目链接

点击打开链接

题目解法

  • 做法1
    一个沙子消失,会带走所有它所在列下面的沙子
    我们记每列从下往上第 \(a_i\) 个沙子为关键点,第 \(i\) 列至少消失 \(a_i\) 个沙子等价于所有关键点都消失
    一个显然的事情是:记一列最上面的沙子为起始点,则我们只会干扰起始点
    第一感觉是找到一个沙子可以干扰的所有起始点,但它并不是一个列上的区间
    但把这个东西反过来,一个沙子能被干扰到的起始点是一个区间
    证明:假设存在 \(i<k<R_i\)(左边部分类似),第 \(i\) 列的关键点不能被第 \(k\) 列的起始点干扰。如果第 \(R_i\) 列的起始点干扰第 \(i\) 列关键点的路径从第 \(k\) 列起始点的上方经过,那么第 \(k\) 列的起始点的起始点上方就有沙子,矛盾;如果路径从下方经过,那么第 \(k\) 列的起始点能干扰第 \(i\) 列的关键点,矛盾。
    不难用 \(dfs\) 求出所有关键点能被干扰到的起始点的区间,现在问题变成有很多区间,我们要选最少的点,使得每个区间中都存在选择的点
    这显然可以按右端点排序之后贪心求出
    时间复杂度 \(O(nm\log m)\)
  • 做法2
    沿用 F1 的思路,我们只把关键点缩点,且只需要关注度数为 \(0\) 的点
    根据做法 1 的结论,非关键点能干扰的度数为 \(0\) 的点是一个区间,然后类似做法 1 一样做就好了
    其实两个做法本质是相同的

做法 1 的代码:

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=400010;
int n,m,a[N],L[N],R[N];
bool mp[N];
char str[N];
int ind(int x,int y){ return (x-1)*m+y;}
void dfs1(int x,int y,int col){
    if(L[ind(x,y)]) return;
    L[ind(x,y)]=col;
    if(x<n) dfs1(x+1,y,col);
    if(x>1&&mp[ind(x-1,y)]) dfs1(x-1,y,col);
    if(y>1&&mp[ind(x,y-1)]) dfs1(x,y-1,col);
    if(y<m&&mp[ind(x,y+1)]) dfs1(x,y+1,col);
}
void dfs2(int x,int y,int col){
    if(R[ind(x,y)]) return;
    R[ind(x,y)]=col;
    if(x<n) dfs2(x+1,y,col);
    if(x>1&&mp[ind(x-1,y)]) dfs2(x-1,y,col);
    if(y>1&&mp[ind(x,y-1)]) dfs2(x,y-1,col);
    if(y<m&&mp[ind(x,y+1)]) dfs2(x,y+1,col);
}
pii rng[N];
int main(){
    read(n),read(m);
    F(i,1,n){
        scanf("%s",str+1);
        F(j,1,m) if(str[j]=='#') mp[ind(i,j)]=1;
    }
    F(i,1,m) read(a[i]);
    F(j,1,m) F(i,1,n) if(mp[ind(i,j)]) dfs1(i,j,j);
    DF(j,m,1) F(i,1,n) if(mp[ind(i,j)]) dfs2(i,j,j);
    int cnt=0;
    F(j,1,m) if(a[j])
        DF(i,n,1) if(mp[ind(i,j)])
            if(!(--a[j])){
                rng[++cnt]={R[ind(i,j)],L[ind(i,j)]};
                break;
            }
    sort(rng+1,rng+cnt+1);
    int cur=0,ans=0;
    F(i,1,cnt) if(rng[i].second>cur) ans++,cur=rng[i].first;
    printf("%d\n",ans);
    return 0;
}

标签:ch,CF1534F2,题解,Hard,&&,沙子,关键点,col,define
From: https://www.cnblogs.com/Farmer-djx/p/18403181

相关文章

  • LOJ4218 「IOI2024」尼罗河船运 题解
    题目描述有\(n\)件手工艺品,第\(i\)件重量为\(w_i\),有参数\(a_i\)和\(b_i\)。每艘船最多可以运输两件手工艺品:如果只运输第\(i\)件,重量没有要求,代价为\(a_i\)。如果同时运输第\(i\)和第\(j\)件,要求\(|w_i-w_j|\leD\),代价\(b_i+b_j\)。\(q\)次询问,给......
  • Leetcode第 414 场周赛题解
    Leetcode第414场周赛题解Q1.将日期转换为二进制表示给你一个字符串date,它的格式为yyyy-mm-dd,表示一个公历日期。date可以重写为二进制表示,只需要将年、月、日分别转换为对应的二进制表示(不带前导零)并遵循year-month-day的格式。返回date的二进制表示。解法:STL一......
  • 题解:P11020 「LAOI-6」Radiation
    我们发现一种最优策略,把石头按照斜线摆,即(1,1),......
  • P1419 寻找段落 题解
    其他学习笔记这题真是凝聚了很多精华,那么我们就介绍这题的四兄弟:大哥平均数这道题是其他兄弟的基础。二哥BestCow这位更是重量级,因为没特长只能强大哥的外貌,会大哥即识二哥。三哥PROSJEK这位哥看似有点创新却仍没逃过一家子的基因,只是变为了小数运算。四哥寻......
  • 【题解】CPS-S模拟2
    目录PreT1.不相邻集合题目描述部分分40pts10pts正解思路代码T2.线段树题目描述部分分20pts正解思路代码T3.部分分40pts正解思路代码T4.部分分10pts正解思路代码AndPre赛时没有第一时间找到签到题,遂四处游走,后来决定先打T1,约1h时切了,然后1h打后3题暴力,后面推了推T4一个特殊性质,......
  • [ABC370C] Word Ladder 题解
    题目描述:给予两个相等长度的序列,\(S\)与\(T\),以及一个空数组\(X\),每在\(S\)上修改一个字符,便将修改后的\(S\)加入\(X\)中,直到\(S\)与\(T\)相同。(输出字典序最小的\(X\)数组)拿过题一看,感觉还是蛮简单的,本题主要的难点在字符串的字典序上。字符串字典序的定义......
  • P11019 「LAOI-6」[太阳]] 请使用最新版手机 QQ 体验新功能 题解
    非常简单的模拟题。由题意得,即找出输入字符串中,用[]围起来的片段中的大写字母\(A_1,A_2,A_3...A_n\)然后将其转换为小写输出\(/a_1a_2a_3...a_n\)即可。#include<bits/stdc++.h>#defineseq(q,w,e)for(intq=w;q<=e;q++)#definelllonglongusingnamespace......
  • P11020 「LAOI-6」Radiation 题解
    一道简单的构造题,其实不用想的十分复杂的说。首先,最多发射的宇宙射线\(sum\)也最多为\(sum_{max}=min(m,n)\)也就是说,无论如何摆放石子,也只能达到这个数量。那么我们的目的便变成了如何让石子变成这一个形状。如上图,在一个\(3\times6\)的矩阵中,其实只要三颗石子即可满足......
  • AtCoder Beginner Contest 370 A-F题解
    A#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;mt19937rnd(time(0));#defineintlonglongtypedeftuple<int,int,int>tp;#definexfirst#defineysecondtypedefpair<int,int>pii;typedefpair<double,double>......
  • 配置PHP的Session存储到Mysql / Redis / memcache 以及使用opcache以及apc缓存清除工
    一、配置PHP的Session存储到Mysql,Redis以及memcache等        PHP的会话默认是以文件的形式存在的,可以通过简单的配置到将Session存储到NoSQL中,即提高了访问速度,又能很好地实现会话共享!1.默认配置:session.save_handler=filessession.save_path=/tmp/2.配......