【Atcoder】 [ARC149D] Simultaneous Sugoroku

文章描述了一种针对特定问题的解题策略,该策略利用了数轴上点的对称性质,通过维护一部分信息来推导出其他对称点的状态。在处理过程中,动态调整维护区间,并在原点移动时考虑不同情况,以减少需要存储的数据量。代码实现中涉及到了深度优先搜索DFS和图的构建。
摘要由CSDN通过智能技术生成

题目链接

Atcoder方向
Luogu方向

题目解法

首先可以观察到一个 s i m p l e simple simple 的性质:两个相反数每次移动到的位置也是相反数
同时因为坐标的范围较小,所以可以考虑维护一部分位置的信息,来推出其他与它对称的点的信息
首先维护 l , r l,r l,r,表示当前只维护 l − r l-r lr 的信息,同时维护 p o s pos pos 表示当前原点所在位置
考虑把位置的移动变成原点的移动,这样每个位置与原点的相对位置是不会发生改变的
如果原点在 l , r l,r l,r 之间,需分情况讨论

  1. r − p o s > p o s − l r-pos>pos-l rpos>posl,即在原点右边的部分较大,考虑只维护原点右边的部分,舍弃原点左边的部分,只需要将右边的部分指向左边的部分,表示这两个点对称,答案相反即可
  2. r − p o s < = p o s − l r-pos<=pos-l rpos<=posl,同理

最后考虑 x = p o s x=pos x=pos 的情况,即可以移到原点,只要将与它对称的点都标记可以移到原点即可

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
const int N(1000100);
int n,m,a[N],ed[N],ans[N];
bool vis[N];
int e[N],h[N],ne[N],idx;
inline int read(){
	int FF=0,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;
	return FF*RR;
}
void dfs(int u){
	for(int i=h[u];~i;i=ne[i]){
		int v=e[i];
		ans[v]=-ans[u],ed[v]=ed[u];
		dfs(v);
	}
}
void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int main(){
	memset(h,-1,sizeof(h));
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	int l=1,r=1e6,pos=0;
	for(int i=1;i<=m;i++){
		int d=read();
		if(l>pos) pos+=d;
		else pos-=d;
		//l,r,pos的相对位置不影响 
		if(pos<l||pos>r) continue;//l,r不会被割开 
		if(pos-l<r-pos){
			//从多的部分指向少的部分,只保存多的部分继续往下做,少的部分通过对称得出 
			for(int i=l;i<pos;i++) add(2*pos-i,i),vis[i]=1;/*i不可以做开始点*/
			l=pos+1,ed[pos]=i;
		}
		else{
			for(int i=pos+1;i<=r;i++) add(2*pos-i,i),vis[i]=1;
			r=pos-1,ed[pos]=i;
		}
	}
	for(int i=l;i<=r;i++) ans[i]=i-pos;
	for(int i=1;i<=1e6;i++) if(!vis[i]) dfs(i);
	for(int i=1;i<=n;i++)
		if(ed[a[i]]) printf("Yes %d\n",ed[a[i]]); 
		else printf("No %d\n",ans[a[i]]);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值