有关此题的二分写法
查看原帖
有关此题的二分写法
234224
青鸟_Blue_Bird楼主2020/6/12 15:19

RT,为什么本蒟蒻将l和r的定义换个位置,就会导致输出结果不一样???

使用全局变量::

#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define isdigit(c) ((c)>='0'&&(c)<='9')

inline void swap(int& x, int& y){
	x ^= y ^= x ^= y;
	return ;
}

int read(){
	int x = 0, s = 1;
	char c = getchar();
	while(!isdigit(c)){
		if(c == '-') s = -1;
		c = getchar();
	}
	while(isdigit(c)){
		x = (x << 1) + (x << 3) + (c ^ '0');
		c = getchar(); 
	}
	return x * s;
}

struct node{
	int v, w;
	int next;
} t[N];
int f[N];
int n, m;
int l, r;   /*定义成全局变量*/

struct ask{
	int x, y;
	int lca, dis;
} a[N];

int bian = 0;
inline void add(int u, int v, int w){
	t[++bian] = (node){v, w, f[u]}, f[u] = bian;
	t[++bian] = (node){u, w, f[v]}, f[v] = bian;
	return ;
}

int dfn[N], top[N], fa[N], son[N], siz[N];
int dis[N], id = 0, val[N];
int deth[N];

void dfs1(int now, int father){
	fa[now] = father;
	deth[now] = deth[father] + 1;
	dfn[++id] = now;
	siz[now] = 1;
	for(int i = f[now]; i; i = t[i].next){
		int v = t[i].v, w = t[i].w;
		if(v != father){
			dis[v] = dis[now] + w;
			val[v] = w;
			dfs1(v, now);
			siz[now] += siz[v];
			if(siz[v] > siz[son[now]] )
				son[now] = v; 
		}
	}	 
	return ;
}

void dfs2(int now, int tp){
	top[now] = tp;
	if(!son[now]) return ;
	dfs2(son[now], tp);
	for(int i = f[now]; i; i = t[i].next){
		int v = t[i].v;
		if(v != fa[now] && v != son[now])
			dfs2(v, v);
	}
	return ;
}

int get_lca(int x, int y){
	while(top[x] != top[y]){
		if(deth[top[x]] < deth[top[y]]) swap(x, y);
		x = fa[top[x]];
	}
	return deth[x] < deth[y] ? x : y;
}
/*树链剖分结束*/
int sum[N];

int check(int lim){
	int cnt = 0;
	memset(sum, 0, sizeof(sum));
	for(int i = 1;i <= m; i++){
		if(a[i].dis > lim){
			sum[a[i].x]++, sum[a[i].y]++, sum[a[i].lca] -= 2;
			cnt++; 
		}
	}
	for(int i = n; i > 0; i--){
		sum[fa[dfn[i]]] += sum[dfn[i]];
		if(val[dfn[i]] >= r - lim && sum[dfn[i]] == cnt)
			return 1;
	}
	return 0;
}

int erfen(int l, int r, int mid = 0){
	while(l < r){
		mid = l + r >> 1;
		if(check(mid)) r = mid;
		else l = mid + 1;
	}
	return l;
}

int main(){
//	freopen("P2680_2.in", "r", stdin);
	n = read(), m = read();
	l = 0, r = 0;  /*利用全局变量*/
	for(int i = 1;i < n; i++){
		int x = read(), y = read(), w = read();
		add(x, y, w);
		l = max(l, w);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	for(int i = 1;i <= m; i++){
		int x = read(), y = read(), lca = get_lca(x, y);
		a[i].x = x, a[i].y = y;
		a[i].lca = lca;
		a[i].dis = dis[x] + dis[y] - (dis[lca] << 1);
		r = max(r, a[i].dis);
	}
	int ans = erfen(r - l, r + 1);
	printf("%d\n", ans);
	return orz;
}

用函数传入:

#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define isdigit(c) ((c)>='0'&&(c)<='9')

inline void swap(int& x, int& y){
	x ^= y ^= x ^= y;
	return ;
}

int read(){
	int x = 0, s = 1;
	char c = getchar();
	while(!isdigit(c)){
		if(c == '-') s = -1;
		c = getchar();
	}
	while(isdigit(c)){
		x = (x << 1) + (x << 3) + (c ^ '0');
		c = getchar(); 
	}
	return x * s;
}

struct node{
	int v, w;
	int next;
} t[N];
int f[N];
int n, m;
//int l, r;   /*定义成全局变量*/

struct ask{
	int x, y;
	int lca, dis;
} a[N];

int bian = 0;
inline void add(int u, int v, int w){
	t[++bian] = (node){v, w, f[u]}, f[u] = bian;
	t[++bian] = (node){u, w, f[v]}, f[v] = bian;
	return ;
}

int dfn[N], top[N], fa[N], son[N], siz[N];
int dis[N], id = 0, val[N];
int deth[N];

void dfs1(int now, int father){
	fa[now] = father;
	deth[now] = deth[father] + 1;
	dfn[++id] = now;
	siz[now] = 1;
	for(int i = f[now]; i; i = t[i].next){
		int v = t[i].v, w = t[i].w;
		if(v != father){
			dis[v] = dis[now] + w;
			val[v] = w;
			dfs1(v, now);
			siz[now] += siz[v];
			if(siz[v] > siz[son[now]] )
				son[now] = v; 
		}
	}	 
	return ;
}

void dfs2(int now, int tp){
	top[now] = tp;
	if(!son[now]) return ;
	dfs2(son[now], tp);
	for(int i = f[now]; i; i = t[i].next){
		int v = t[i].v;
		if(v != fa[now] && v != son[now])
			dfs2(v, v);
	}
	return ;
}

int get_lca(int x, int y){
	while(top[x] != top[y]){
		if(deth[top[x]] < deth[top[y]]) swap(x, y);
		x = fa[top[x]];
	}
	return deth[x] < deth[y] ? x : y;
}
/*树链剖分结束*/
int sum[N];

int check(int r, int lim){
	int cnt = 0;
	memset(sum, 0, sizeof(sum));
	for(int i = 1;i <= m; i++){
		if(a[i].dis > lim){
			sum[a[i].x]++, sum[a[i].y]++, sum[a[i].lca] -= 2;
			cnt++; 
		}
	}
	for(int i = n; i > 0; i--){
		sum[fa[dfn[i]]] += sum[dfn[i]];
		if(val[dfn[i]] >= r - lim && sum[dfn[i]] == cnt)
			return 1;
	}
	return 0;
}

int erfen(int l, int r, int mid = 0){
	while(l < r){
		mid = l + r >> 1;
		if(check(r, mid)) r = mid;
		else l = mid + 1;
	}
	return l;
}

int main(){
//	freopen("P2680_2.in", "r", stdin);
	n = read(), m = read();
	int l = 0, r = 0;  /*利用函数传入*/
	for(int i = 1;i < n; i++){
		int x = read(), y = read(), w = read();
		add(x, y, w);
		l = max(l, w);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	for(int i = 1;i <= m; i++){
		int x = read(), y = read(), lca = get_lca(x, y);
		a[i].x = x, a[i].y = y;
		a[i].lca = lca;
		a[i].dis = dis[x] + dis[y] - (dis[lca] << 1);
		r = max(r, a[i].dis);
	}
	int ans = erfen(r - l, r + 1);
	printf("%d\n", ans);
	return orz;
}

(就是代码里面注释的地方)

第一种: AC 第二种: 65PTS

蒟蒻表示不知道第二种哪里出问题了

2020/6/12 15:19
加载中...