首页 > 其他分享 >题解 [ABC186F] Rook on Grid

题解 [ABC186F] Rook on Grid

时间:2024-01-20 11:44:57浏览次数:22  
标签:Rook ABC186F 题解 fenwick tree const dt SIZE

【洛谷博客】

有一点难度,但不多。

题意

一个 \(H \times W\) 的地图上有 \(M\) 个障碍物。

有一辆车在 \((1,1)\),一次行动可以向下或向右移动任意格(不得穿过障碍物)。

求这辆车在最多两次行动中可能到达多少个格子。

分析

车有四种选择:向右、向下、先向右再向下、先向下再向右。

然后设 \(h_i\) 表示第 \(i\) 行最右边可以到达的列,\(l_j\) 表示第 \(j\) 列最下边可以到达的行。

很显然总答案为 \(\sum\limits_{i=1}^{h_1}l_i + \sum\limits_{i=1}^{l_1}h_i - \text{重复计算的部分}\),接下来难点就在于如何计算重复的部分。

考虑对于每一列 \(i \in [1,h_1]\),被重复计算的就等于 \(\sum\limits_{j=1}^{\min(l_1,l_i)}[h_j \ge i]\)。

直接计算的复杂度是 \(O(HW)\),无法接受。

题解区中 Lyccrius 大佬的题解使用了权值线段树,但是显然我不会,考虑换一种想法。

对于每个查询区间的左端点都是固定的,只需要让右端点单调不减,再用一个大小为 \(W\) 的树状数组记录出现次数即可,均摊单次复杂度 \(O(\log W)\)。

总体时间复杂度 \(O(W \log W)\),可以通过此题。

代码

//the code is from chenjh
#include<cstdio>
#include<cstring>
#define NDEBUG
#include<cassert>
#include<algorithm>
#define MAXN 200005
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
template<typename T>
struct fenwick_tree{//树状数组模板。
    public:
        fenwick_tree(int _SIZE=0):SIZE(_SIZE){dt=new T[SIZE+1]();memset(dt,0,sizeof(T)*(SIZE+1));}
        fenwick_tree(const fenwick_tree& y):SIZE(y.size()),dt(new T[y.size()+1]){memcpy(dt,y.get_dt(),sizeof(T)*(SIZE+1));}
        ~fenwick_tree(){delete[] dt;}
        const T&operator [] (const int&x)const{assert(0<x&&x<=SIZE);return dt[x];}
        fenwick_tree&operator = (const fenwick_tree&y){if(this!=&y){SIZE=y.size();T*new_dt=new T[SIZE+1]();memcpy(new_dt,y.get_dt(),sizeof(T)*(SIZE+1));delete[] dt;dt=new_dt;}return *this;}
        inline void resize(int _SIZE){T*new_dt =new T[_SIZE+1]();memcpy(new_dt,dt,sizeof(T)*((SIZE<_SIZE?SIZE:_SIZE)+1));delete[] dt;dt=new_dt,SIZE=_SIZE; }
        inline void clear(){SIZE=0;delete[] dt;dt=new T[SIZE+1]();memset(dt,0,sizeof(T)*(SIZE+1));}
        inline int size()const{return SIZE;}
        inline T* get_dt()const{return dt;}
        inline void add(int x,const T&v){assert(0<x&&x<=SIZE);for(;x<=SIZE;x+=x&-x)dt[x]+=v;}
        inline T sum(const int&l,const int&r)const{assert(0<l&&l<=r&&r<=SIZE);return sum(r)-sum(l-1);}
    private:
        T*dt=nullptr;
        int SIZE;
        inline T sum(int x)const{assert(0<=x&&x<=SIZE);T ret(0);for(;x;x^=x&-x)ret+=dt[x];return ret;}
};
int n,m,t;
int h[MAXN],l[MAXN];//同题解中的描述。
PII q[MAXN];//查询区间。
int main(){
	scanf("%d%d%d",&n,&m,&t);
	fill_n(h+1,n,m),fill_n(l+1,m,n);//记得初始化最远的边界。
	for(int x,y;t--;) scanf("%d%d",&x,&y),h[x]=min(h[x],y-1),l[y]=min(l[y],x-1);//注意需要减一,因为是可以到达的。
	LL ans=0;
	for(int i=1;i<=h[1];i++) ans+=l[i],q[i]=make_pair(min(l[1],l[i]),i);
	for(int i=1;i<=l[1];i++) ans+=h[i];
	sort(q+1,q+h[1]+1);//按照右端点从小到大排序。
	static fenwick_tree<int> T(m);
	for(int i=1,j=1;i<=h[1];i++){
		for(;j<=q[i].first;j++)T.add(h[j],1);//扩展查询区间。
		ans-=T.sum(q[i].second,m);
	}
	printf("%lld\n",ans);
	return 0;
}

标签:Rook,ABC186F,题解,fenwick,tree,const,dt,SIZE
From: https://www.cnblogs.com/Chen-Jinhui/p/17976215/solution-at-abc186-f

相关文章

  • 题解 [ABC186E] Throne
    【洛谷博客】同余方程板子题,没过的可以先去看看。题意翻译给的很清楚。分析看到这个转圈圈的就很容易想到同余方程。为了方便处理,我们就将编号全部减\(1\),于是编号就变成\(0\simN-1\)。然后就可以很容易的列出同余方程:\[S+Kx\equiv0\pmod{N}\]移项可得:\[Kx\equ......
  • 题解 [ABC236D] Dance
    【洛谷博客】简单搜索题。题意将\(2N\)个人两两分组,每两个人配对会有一个快乐值,求快乐值异或最大。分析观察数据范围\(N\le8\),很容易想到搜索。又因为\(2N\le16\),所以直接枚举全排列不可行,需要做一点优化。第\(i\)个人和第\(j\)个人配对产生的快乐值,与第\(j\)......
  • 洛谷入门赛 #19 题解
    比赛传送门A-分饼干I将三盒饼干按数量排序。若较小的两盒饼干数之和大于另一盒饼干,则将较小的两盒饼干奖励给第一名,另一盒奖励给第二名;若较大的一盒饼干数大于另外两盒之和,则将较大的一盒奖励给第一名,另外两盒奖励给第二名。B-分饼干II每个人分到的饼干数都不同,即可以看......
  • CF1898D Absolute Beauty 题解
    Problem-D-Codeforcesemm,怎么说呢?因为想起之前那个直接去掉绝对值取最大时就是答案的影响,这题并没有想到正确做法。(或者说想到了正确做法,但是因为不知道一个性质所以要大分讨)假如原题满足\(a_i<b_i\),则我们把原题抽象成线段\((a_i,b_i)\),考虑两条线段合并时的情况:......
  • P8512 [Ynoi Easy Round 2021] TEST_152 题解
    题目链接:[YnoiEasyRound2021]TEST_152题目比较抽象,翻译一下。就是有\(n\)个操作,每个操作为\((l_i,r_i,v_i)\)表示把长为\(m\)序列\(a\)的\([l_i,r_i]\)上的数覆盖为\(v_i\)。而查询为\([time_l,time_r]\),表示从\(time_l\)的操作开始执行,到\(time_r\)操作结......
  • [OI] 洛谷P1001过河卒题解
    [NOIP2002普及组]过河卒题目描述棋盘上\(A\)点有一个过河卒,需要走到目标\(B\)点。卒行走的规则:可以向下、或者向右。同时在棋盘上\(C\)点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘用坐标表示,\(A\)点\((0......
  • [BZOJ3786] 星系探索 题解
    题目链接:\(BZOJ\)本题通过\(dyf\_DYF\)的题解理解\(ETT\),代码则借鉴\(lcyfrog\)的题解,图片则使用了何太郎的题解。在此笔者感谢这三位神犇。声明变量:\(ls\):左儿子\(rs\):右儿子\(sz\):子树大小\(rk\):对应堆值\(fa\):节点父亲\(sm\):子树权值和\(p\):\(1/-1\)表示第一......
  • P4345 [SHOI2015] 超能粒子炮·改 题解
    P4345[SHOI2015]超能粒子炮·改题解求\[\sum_{i=0}^k\binom{n}{i}\pmod{2333}\]思路这种模数小的组合数计数问题可以考虑Lucas定理,试试呗。如果按余数分类不好优化,可以按商分类求和,这样一来套个前缀和可以得到一个递推式,注意最后一块商可能是不整的,单独拿出来即可。......
  • GD动角题解(2024.1.19)
    $upd:$2024.1.19改正了一些错误题目讲解只看第三题若在三角板开始转动的同时,射线\(OC\)也绕点\(O\)以每秒25°的速度逆时针旋转一周,从旋转开始多长时间,射线\(OC\)平分\(∠BOD\)?最重要的一点:动角角度\(=\)初始值\(+\)角度\((vt)\)明确了这一点之后我们看题这题可以分......
  • 题解:阶乘
    题目大意给定一个数\(n\),求两个数\(a\),\(b\),使\(\Large\frac{a!}{b!}\normalsize=n(a>b)\)。若有无数组解输出-1。多组数据。思路简析\[a!=a\times(a-1)\times(a-2)\times\cdots\times2\times1\]\[b!=b\times(b-1)\times(b-2)\times\cdots\times2\times1\]......