题解 [ABC186F] Rook on Grid
有一点难度,但不多。
题意
一个
有一辆车在
求这辆车在最多两次行动中可能到达多少个格子。
分析
车有四种选择:向右、向下、先向右再向下、先向下再向右。
然后设
很显然总答案为
考虑对于每一列
直接计算的复杂度是
题解区中 Lyccrius 大佬的题解使用了权值线段树,但是显然我不会,考虑换一种想法。
对于每个查询区间的左端点都是固定的,只需要让右端点单调不减,再用一个大小为
总体时间复杂度
代码
//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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App