cf round 751 D.Frog Traveller(bfs剪枝和线段树优化建图做法)

6 篇文章 0 订阅
3 篇文章 0 订阅
#include<bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
const int N = 3e6 + 5;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
#define lc(x) (x << 1)
#define rc(x) ((x << 1) | 1)
ll fast_pow(ll a,ll b){ll ans = 1;while(b){if(b&1)ans = (ans * a)%mod;a = (a * a)%mod;b>>=1;}return (ans%mod);}
inline ll read(){ll X=0; bool flag=1; char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}if(flag) return X;return ~(X-1);}
inline void write(ll X){if(X<0) {X=~(X-1); putchar('-');}if(X>9) write(X/10);putchar(X%10+'0');}
typedef pair<int,int> pii;
typedef vector<int> vi;
inline void fastIO(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
inline void time_cost(clock_t start_time,clock_t end_time){cout << "The run time is: " <<(double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << endl;}
inline void init(){	
	
}
bool is_start[N],one_step[N];
vector<pii> g[N];
int dis[N];
int point[4 * 300005],leaf[4 * 300005];
const int D = 1300000;
int n,a[300005],b[300005];
int pre2[N],pre1[N];
bool vis[N];
void build(int x,int l,int r){
	if(l == r){
		leaf[l] = x;
		point[x] = l;
		return; 
	}
	int mid = (l + r) >> 1;
	g[x].pb(mp(lc(x),0));
	g[x].pb(mp(rc(x),0));
	build(lc(x),l,mid);
	build(rc(x),mid + 1,r);
}
void connect(int x,int curl,int curr,int u,int ql,int qr){
	if(ql <= curl && qr >= curr){
		g[u].pb(mp(x,1));
		return;
	}
	int mid = (curl + curr) >> 1;
	if(qr <= mid)
		connect(lc(x),curl,mid,u,ql,qr);
	else if(ql > mid)
		connect(rc(x),mid + 1,curr,u,ql,qr);
	else
		connect(lc(x),curl,mid,u,ql,qr),connect(rc(x),mid + 1,curr,u,ql,qr);
}

inline void solve(){
	init();
	cin >> n;
	for(int i = 1;i <= n;i++)cin >> a[i];
	for(int i = 1;i <= n;i++)cin >> b[i];
	build(1,1,n);
	for(int i = n;i >= 1;i--){
		if(a[i] == i)
			one_step[leaf[i] + D] = 1;
		else
			connect(1,1,n,leaf[i] + D,i - a[i],i);
		is_start[leaf[i] + D] = 1;
	}
	for(int i = 1;i <= n;i++)g[leaf[i]].pb(mp(leaf[i + b[i]] + D,0));
	memset(dis,0x3f,sizeof(dis));
	dis[leaf[n] + D] = 0;
	priority_queue<pii,vector<pii>,greater<pii> > q;
	q.push(mp(0,leaf[n] + D));
	pre2[leaf[n] + D] = -1;
	while(!q.empty()){
		auto p = q.top();q.pop();
		int tmp = p.fi,u  = p.se;
		if(vis[u])continue;
		vis[u] = 1;
		if(one_step[u]){
			dis[0] = tmp + 1;
			pre1[0] = u;
			break;
		}
		for(auto pp:g[u]){
			int v = pp.fi,w = pp.se;
			if(dis[v] > dis[u] + w){
				dis[v] = dis[u] + w;
				if(is_start[u])
					pre1[v] = u;
				else
					pre1[v] = pre1[u];
				if(is_start[v] && pre2[v] == 0)
					pre2[v] = point[u];
				q.push(mp(dis[v],v));
			}
		}
	}
	if(dis[0] == INF){
		cout << -1 << endl;
		return;
	}
	vector<int> ans;
	ans.pb(0);
	int pre = pre2[pre1[0]];
	while(pre != -1){
		ans.pb(pre);
		pre = pre2[pre1[leaf[pre]]];
	}
	cout << ans.size() << endl;
	for(int i = ans.size() - 1;i >= 0;i--)
		cout << ans[i] << " ";
} 
int main(){
	fastIO();
#if DBG
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
#endif
	
	solve();

	return 0;
}

bfs剪枝

#include<bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
const int N = 3e5 + 5;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
ll fast_pow(ll a,ll b){ll ans = 1;while(b){if(b&1)ans = (ans * a)%mod;a = (a * a)%mod;b>>=1;}return (ans%mod);}
inline ll read(){ll X=0; bool flag=1; char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}if(flag) return X;return ~(X-1);}
inline void write(ll X){if(X<0) {X=~(X-1); putchar('-');}if(X>9) write(X/10);putchar(X%10+'0');}
typedef pair<int,int> pii;
typedef vector<int> vi;
inline void fastIO(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
inline void time_cost(clock_t start_time,clock_t end_time){cout << "The run time is: " <<(double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << endl;}
inline void init(){	
	
}
int dis[N],ans[N],pre[N],n,a[N],b[N];
int minn = INF;
inline void solve(){
	init();
	cin >> n;
	for(int i = 1;i <= n;i++)cin >> a[i];
	for(int i = 1;i <= n;i++)cin >> b[i];
	memset(dis,0x3f,sizeof(dis));
	memset(pre,-1,sizeof(pre));
	queue<int> q;
	dis[n] = 0;
	q.push(n);
	while(!q.empty()){
		int cur = q.front();q.pop();
		if(cur - a[cur] == 0){
			pre[0] = cur;
			ans[0] = 0;
			break;
		}
		for(int i = a[cur];i >= 0;i--){
			if(cur - i >= minn)break;
			int to = cur - i;
			int slip = to + b[to];
			if(dis[slip] > dis[cur] + 1){
				dis[slip] = dis[cur] + 1;
				q.push(slip);
				pre[slip] = cur;
				ans[slip] = to; 
			}
		}
		minn = min(minn,cur - a[cur]);
	}
	if(pre[0] == -1){
		cout << -1 << endl;
		return;
	}
	int cur = 0;
	vector<int > res;
	while(pre[cur] != -1){
		res.pb(ans[cur]);
		cur = pre[cur];
	}
	cout <<res.size() << endl;
	for(int i = res.size() - 1;i >= 0;i--)
		cout << res[i] << " ";
} 
int main(){
	fastIO();
#if DBG
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
#endif
	solve();

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值