社区讨论

求条代码

CF1859FTeleportation in Byteland参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhj0vhkr
此快照首次捕获于
2025/11/03 18:53
4 个月前
此快照最后确认于
2025/11/03 18:53
4 个月前
查看原帖
CPP
/*
1.Binary Search?
2.Dynamic Program?
3.Data Structure?
4.Monotonic?
5.Modulo?
6.Tarjan?
7.Offline?
8.ChthollyTree? (Mo's Algorithm?)
9.SimulateAnneal? (That's not possible)



1.Think Backward?
2.Make Charts?
3.Find Features?
4.Widen Constraints?
5.Answer = All - Illegal
6.Skip the process.Focus on the result
*/
#include<bits/stdc++.h>

#define int long long

using namespace std;

constexpr int inf = 1e18;

int n = 0 , T = 0 , q = 0 , cnt = 0 , dfs_time = 0;

array<int , 200100> head , son , top , dep , up , sizes , dfn , len;

array<int , 3000100> Log;

array<int , 30> pre;

array<bool , 100100> tag , vis;

array<array<int , 100100> , 25> dis;

array<array<array<int , 2> , 100100> , 25> dp;

struct Node{
	int to;
	int nxt;
	int val;
};

array<Node , 400100> edge;

struct Lilies{
	int s;
	int t;
	int ans;
};

array<Lilies , 400100> quest;

priority_queue<pair<int , int> , vector<pair<int , int> > , greater<pair<int , int> > > que;

void new_line(int a , int b , int c)
{
	edge[++ cnt].to = b;
	edge[cnt].nxt = head[a];
	edge[cnt].val = c;
	head[a] = cnt;
	
	return;
}

int get_lca(int x , int y)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x , y);
		x = up[top[x]];
	}
	
	return dep[x] > dep[y] ? y : x;
}

int calc(int id , int x , int y)
{
	int LCA = get_lca(x , y);
	return dis[id][x] + dis[id][y] - 2 * dis[id][LCA];
}

int ask(int id , int l , int r)
{
	int base = Log[r - l + 1];
	
	return min(dp[base][l][id] , dp[base][r - pre[base] + 1][id]);
}

int query(int id , int x , int LCA)
{
	int res = inf;
	
	while(top[x] != top[LCA])
	{
		res = min(res , ask(id , dfn[top[x]] , dfn[x]));
		x = up[top[x]];
	}
	
	return min(res , ask(id , dfn[LCA] , dfn[x]));
}

void dfs1(int x , int fa)
{
	dep[x] = dep[fa] + 1;
	sizes[x] = 1 , up[x] = fa;
	
	for(int e = head[x];e;e = edge[e].nxt)
	{
		int to = edge[e].to;
		
		if(to == fa) continue;
		
		int val = edge[e].val << 1;
		
		for(int j = 0;j <= 21;++ j) dis[j][to] = dis[j][x] + (val = (val + 1) >> 1);
		
		dfs1(to , x);
		
		sizes[x] += sizes[to];
		
		if(!son[x] || sizes[son[x]] < sizes[to]) son[x] = to;
	}
	
}
void dfs2(int x , int tmp)
{
	top[x] = tmp;
	dfn[x] = ++ dfs_time;
	
	if(son[x]) dfs2(son[x] , tmp);
	
	for(int e = head[x];e;e = edge[e].nxt)
	{
		int to = edge[e].to;
		
		if(to != up[x] && to != son[x]) dfs2(to , to);
	}
	
	return;
}
void precalc(int lv)
{
	for(int i = 1;i <= n;++ i)
	{
		len[i] = tag[i] ? 0 : inf , vis[i] = 0;
		
		if(tag[i]) que.push({len[i] , i});
	}
	
	while(!que.empty())
	{
		int x = que.top().second;
		
		que.pop();
		
		if(vis[x]) continue;
		
		vis[x] = 1;
		
		for(int e = head[x];e;e = edge[e].nxt)
		{
			int to = edge[e].to , val = edge[e].val;
			
			if(len[to] > len[x] + val + ((val - 1) / pre[lv]) + 1)
			{
				len[to] = len[x] + val + ((val - 1) / pre[lv]) + 1;
				que.push({len[to] , to});
			}
		}
		
	}
	for(int i = 1;i <= n;++ i)
	{
		dp[0][dfn[i]][0] = len[i] + dis[lv][i] - dis[0][i];
		dp[0][dfn[i]][1] = len[i] - dis[lv][i] + dis[0][i];
	}
	
	for(int i = 1;i <= 21;++ i) for(int j = 1;j + pre[i] - 1 <= n;++ j) for(auto it : {0 , 1}) dp[i][j][it] = min(dp[i - 1][j][it] , dp[i - 1][j + pre[i - 1]][it]);
	
	return;
}

signed main()
{
	
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	
	pre[0] = 1;
	
	for(int i = 1;i <= 21;++ i) pre[i] = pre[i - 1] << 1;
	for(int i = 2;i <= 3e6;++ i) Log[i] = Log[i >> 1] + 1;
	
	int test = 0;
	
	cin >> test;
	
	while(test --)
	{	
		cnt = dfs_time = 0;
		
		cin >> n >> T;
		
		for(int i = 1;i <= n;++ i) head[i] = son[i] = dep[i] = sizes[i] = 0;
		
		for(int i = 1;i < n;++ i)
		{
			int x = 0 , y = 0 , c = 0;
			
			cin >> x >> y >> c;
			
			new_line(x , y , c);
			new_line(y , x , c);
		}
		
		for(int i = 1;i <= n;++ i)
		{
			char ch;
			
			cin >> ch;
			
			tag[i] = ch - '0';
		}
		
		dfs1(1 , 1);
		dfs2(1 , 1);
		
		cin >> q;
		
		for(int i = 1;i <= q;++ i)
		{
			cin >> quest[i].s >> quest[i].t;
			
			quest[i].ans = calc(0 , quest[i].s , quest[i].t);
		}
		
		for(int i = 1;i <= 21;++ i)
		{
			precalc(i);
			
			for(int x = 1;x <= q;++ x)
			{
				int a = quest[x].t , b = quest[x].s;
				
				int LCA = get_lca(a , b);
				
				quest[x].ans = min(quest[x].ans , i * T + dis[0][a] + query(0 , a , LCA) - dis[i][LCA] + dis[i][b] - dis[i][LCA]);
				quest[x].ans = min(quest[x].ans , i * T + dis[0][a] - dis[0][LCA] + query(1 , b , LCA) - dis[0][LCA] + dis[i][b]);
			}
		}
		
		for(int i = 1;i <= q;++ i) cout << quest[i].ans << '\n'; 
	}
	
	cout << endl;
	
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...