题解:P11078 「FSLOI Round I」迷雾
P11078 题解
题面
思路
本蒟蒻太菜了,只会用线段树。。。(准确来说这题是线段森林?)
首先很自然的想到可以按模 k 的余数来分类开线段树,这样每一次在迷雾上的操作就是区间异或,最后于是判断当前节点是否需要改就可以了,思路非常简单,打代码的时候细心点就可以过了。
当然,这样的话要特判下 q=1 的情况,不然会 RE。(别问我怎么知道的)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int MN=2e5+5,MM=505;
ll num,n,m,q,k,x=1,y=1,a,b,dx[5]={0,-1,0,1,0},dy[5]={0,0,1,0,-1};
char mp[MM][MM],op;
struct node{ll num,l,r;bool tag;}t[25][MN<<2];
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
ll gs(ll ch){if(ch=='U') return 1;if(ch=='D') return 3;if(ch=='R') return 2;return 4;}
void build(ll p, ll l, ll r, ll i){
t[i][p].l=l,t[i][p].r=r;t[i][p].tag=false;
if(l==r){
t[i][p].num=0;
return;
}
ll mid=(l+r)>>1;
build(ls,l,mid,i);build(rs,mid+1,r,i);
t[i][p].num=t[i][ls].num+t[i][rs].num;
}
void pushdown(ll p, ll i){
if(t[i][p].tag){
t[i][p].tag=false;
t[i][ls].tag=t[i][ls].tag?false:true;
t[i][rs].tag=t[i][rs].tag?false:true;
t[i][ls].num=t[i][ls].r-t[i][ls].l+1-t[i][ls].num;
t[i][rs].num=t[i][rs].r-t[i][rs].l+1-t[i][rs].num;
}
}
void change(ll p, ll l, ll r, ll i){
if(l<=t[i][p].l&&t[i][p].r<=r){
t[i][p].num=t[i][p].r-t[i][p].l+1-t[i][p].num;
t[i][p].tag=t[i][p].tag?false:true;
return;
}
pushdown(p,i);
ll mid=(t[i][p].l+t[i][p].r)>>1;
if(l<=mid) change(ls,l,r,i);
if(r>mid) change(rs,l,r,i);
t[i][p].num=t[i][ls].num+t[i][rs].num;
}
ll query(ll p, ll x, ll i){
if(t[i][p].l==t[i][p].r) return t[i][p].num;
pushdown(p,i);
ll mid=(t[i][p].l+t[i][p].r)>>1,res=0;
if(x<=mid) res=res^query(ls,x,i);
if(x>mid) res=res^query(rs,x,i);
return res;
}
int main(){
// freopen("1.in","r",stdin);
n=read();m=read();q=read();k=read();
for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) cin>>mp[i][j];
if(q==1){
cin>>op;a=read();b=read();
num=gs(op);
x=max(1ll,min(n,x+dx[num]*a));
y=max(1ll,min(m,y+dy[num]*a));
write(x);putchar(' ');write(y);
return 0;
}
for(int i=0; i<k; i++) build(1,1,q/k,i);
for(int i=1; i<=q; i++){
cin>>op;a=read();b=read();
num=gs(op);
if(query(1,i/k,i%k)){
if(num==1) num=3;
else if(num==2) num=4;
else if(num==3) num=1;
else num=2;
}
x=max(1ll,min(n,x+dx[num]*a));
y=max(1ll,min(m,y+dy[num]*a));
if(mp[x][y]=='X') change(1,i/k+1,min(i/k+b,q/k),i%k);
}
write(x),putchar(' '),write(y);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!