2024模拟赛T3题解
推出神秘结论之后,使用线段树分治即可
code
#include<bits/stdc++.h>
using namespace std;
#define N 506
#define M 200005
int n,m,zu,ID,tot;
const int mod=1145141;
int mp[N][N],las[N][N],id[N][N];
char str[N];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
struct POS{
int x,y,col;
}d[N*N*2];
struct QUE{
int x,y,tx,ty,val;
}wen[M];
vector<int> G[M*4];
void add(int p,int l,int r,int x,int y,int z){
if(x<=l&&r<=y){
G[p].push_back(z);
return ;
}
int mid=(l+r)>>1;
if(x<=mid) add(p*2,l,mid,x,y,z);
if(mid<y) add(p*2+1,mid+1,r,x,y,z);
}
int f[N*N],sz[N*N];
struct COL{
int jmn,jmx,omn,omx;
}se[N*N];
void chu(int x,int y,int col){
int p=id[x][y];
mp[x][y]=col;
if((x+y)&1) se[p]={col,col,10,-1};
else se[p]={10,-1,col,col};
}
int find(int x){
if(f[x]==x) return x;
return find(f[x]);
}
COL mer(COL a,COL b){
return {min(a.jmn,b.jmn),max(a.jmx,b.jmx),min(a.omn,b.omn),max(a.omx,b.omx)};
}
struct SHAN{
int x,y;
COL se;
}q[N*N*4];
int tail;
void merge(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy) return ;
if(sz[fx]<sz[fy]) swap(fx,fy);
q[++tail]={fx,fy,se[fx]};
f[fy]=fx,sz[fx]+=sz[fy],se[fx]=mer(se[fx],se[fy]);
}
void ins(int i){
int x=d[i].x,y=d[i].y,col=d[i].col;
chu(x,y,col);
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(mp[nx][ny]!=-1) merge(id[x][y],id[nx][ny]);
}
}
void del(int nt){
while(tail>nt){
int x=q[tail].x,y=q[tail].y;
f[y]=y,sz[x]-=sz[y],se[x]=q[tail].se,tail--;
}
}
bitset<mod> vis[10][10][2];
void qry(int x,int y,int tx,int ty,int val){
int fx=find(id[x][y]),fy=find(id[tx][ty]);
if(fx!=fy){
printf("No\n");
return ;
}
if(sz[fx]==1&&mp[x][y]!=val){
printf("No\n");
return ;
}
COL co=se[fx];
if(co.jmn==co.jmx&&co.omn==co.omx){
int cs,ce;
if((x+y)&1) cs=co.jmn,ce=co.omn;
else cs=co.omn,ce=co.jmn;
if(vis[cs][ce][(x+y+tx+ty)&1][val]) printf("Yes\n");
else printf("No\n");
return ;
}
printf("Yes\n");
}
void shan(int i){
int x=d[i].x,y=d[i].y;
mp[x][y]=-1;
}
void solve(int p,int l,int r){
int nt=tail;
for(auto id:G[p]) ins(id);
if(l==r){
if(wen[l].x) qry(wen[l].x,wen[l].y,wen[l].tx,wen[l].ty,wen[l].val);
del(nt);
for(auto id:G[p]) shan(id);
return ;
}
int mid=(l+r)>>1;
solve(p*2,l,mid),solve(p*2+1,mid+1,r);
del(nt);
for(auto id:G[p]) shan(id);
}
void dfs(int c1,int c2,int num,int o){
while(1){
if(vis[c1][c2][o][num]) return ;
vis[c1][c2][o][num]=1;
if(!o) num=(num*10+c2)%mod;
else num=(num*10+c1)%mod;
o^=1;
}
}
int main(){
freopen("eternity3.in","r",stdin);
freopen("eternity.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&zu,&ID);
for(int i=0;i<=9;i++){
for(int j=0;j<=9;j++) dfs(i,j,i,0);
}
for(int i=1;i<=n;i++) mp[i][0]=mp[i][m+1]=-1;
for(int i=1;i<=m;i++) mp[0][i]=mp[n+1][i]=-1;
for(int i=1;i<=n;i++){
scanf("%s",str+1);
for(int j=1;j<=m;j++){
if(str[j]=='#') mp[i][j]=-1;
else mp[i][j]=str[j]-'0';
las[i][j]=1,id[i][j]=(i-1)*m+j;
f[id[i][j]]=id[i][j],sz[id[i][j]]=1;
}
}
for(int i=1,op,x,y,num,tx,ty,v;i<=zu;i++){
scanf("%d%d%d",&op,&x,&y);
if(op==1){
scanf("%s",str+1);
if(str[1]=='#') num=-1;
else num=str[1]-'0';
if(num==mp[x][y]) continue;
if(mp[x][y]>=0){
if(i-1>=las[x][y]) d[++tot]={x,y,mp[x][y]},add(1,1,zu,las[x][y],i-1,tot);
}
las[x][y]=i,mp[x][y]=num,wen[i].x=0;
}
else{
scanf("%d%d%d",&tx,&ty,&v);
wen[i]={x,y,tx,ty,v};
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j]<0) continue;
d[++tot]={i,j,mp[i][j]},add(1,1,zu,las[i][j],zu,tot);mp[i][j]=-1;
}
}
solve(1,1,zu);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?