51nod 模拟4

对本次分数的预测:
基本分 \(160\)
平均分\(\leq 100\)
T1, T3 AC人数 \(\leq2\)
至少AC一道题的人数 \(\leq10\)
image
image
image
image
T1贪心
T2倍增
T3 复杂度证明 $T(n) = 2 * T(n/2) + O(nlogn) $ ,每次二分答案是\(O(nlogn)\)
T4 斯坦纳树
考场上写了一个假状压,居然A了

T1
#include<bits/stdc++.h>
using namespace std;
const int N = 1E6+10;
typedef long long ll;
typedef pair<ll, ll> pll;
ll a[N];
ll sum[N];
ll S;
int n;
ll get(pll info){
	return sum[info.second] - sum[info.first - 1];
}
pll get_mx(){
	for(int i = 1; i <= n; ++i) sum[i] =sum[i-1] + a[i];
	pll mn = {sum[0], 0};
	pll ans = {1, 0};
	for(int i = 1; i <= n; ++i){
		mn = min(mn, {sum[i], i});
		if(get(ans) < get({mn.second + 1, i})){
			ans = {mn.second + 1, i};
		}
	}
	return ans;
}
bool check(){
	return get(get_mx()) <= S;
}
void carry(){
	pll res = get_mx();
	cerr<<"now range = " << res.first <<" " << res.second << endl;
	ll mxp = res.first;
	for(int i = res.first +1;i <= res.second; ++i){
		if(a[mxp] < a[i]) mxp = i;
	}
	cerr<<"del " << mxp << endl;
	a[mxp] = 0;
}
int main(){
	ios::sync_with_stdio(false), cin.tie(0),cout.tie(0);
	cin >> n >> S;
	for(int i = 1; i <= n; ++i){
		cin >> a[i];
	}
	int ans = 0;
	for(; !check(); ++ans){
		carry();
	}
	cout << ans << endl;
	return 0;
}
T2
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+10, E = 2 * N, L = 25;
int RG = 20;
int a[N];
int f[N][L];
int n, q;
struct graph{
	struct edge{
		int nxt, to;
	}e[E];
	int head[N], elen;
	void inse(int frm, int to){
		e[++elen] ={head[frm], to};
		head[frm] = elen;
	}
	void insf(int u, int v){
		inse(u, v), inse(v, u);
	}
	int fat[N], dep[N];
	void pre(int u){
		dep[u] = dep[fat[u]] + 1;
		for(int i = head[u];i ;i = e[i].nxt){
			int v = e[i].to;
			if(v == fat[u]) continue;
			fat[v] = u;
			pre(v);
		}
	}
	void init(int u){
		if(a[fat[u]] > a[u]){
			f[u][0] = fat[u];

		}else{
			int fa = fat[u];
			for(int i = RG; i >= 0; --i){
				if(f[fa][i] && a[f[fa][i]] <= a[u]) fa = f[fa][i];

			}
			/*
			if(u == 3){
				cerr<<"fa = " << fa << endl;
			}*/
			f[u][0] = f[fa][0];
		}
		for(int i = 1; i <= RG; ++i){
			f[u][i] = f[f[u][i-1]][i-1];
		}
		for(int i = head[u];i ;i = e[i].nxt){
			int v = e[i].to;
			if(v == fat[u]) continue;
			init(v);
		}
	}
}G;
int main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> q;
	for(int i = 1; i <= n; ++i) cin >> a[i];
	for(int i = 1; i < n; ++i){
		int u, v;
		cin >> u >> v;
		G.insf(u, v);
	}	
	G.pre(1);
	G.init(1);
	/*
	for(int i = 1; i <= n; ++i){
		cerr<<G.dep[i] <<" ";
	}
	cerr<<endl;
	for(int i = 1; i <= n; ++i){
		for(int j = 0; j <= RG;++j){
			cerr<<f[i][j] << " ";
		}
		cerr<<endl;
	}*/
	for(int i = 1; i <= q; ++i){
		int u, v, c;
		cin >> u >> v >> c;
		int ans = 0;
		if(a[u] > c){
			++ans;//先走到u
		}else{
			for(int i = RG; i >= 0; --i){
				if(f[u][i] && a[f[u][i]] <= c) u = f[u][i];
			}
			// cerr<<"!"<<endl;
			// cerr<<
			//先无伤走到u
		}
		if(G.dep[u] >= G.dep[v]){
			for(int i = RG; i >= 0; --i){
				if(f[u][i] &&G.dep[f[u][i]] >= G.dep[v]) u = f[u][i], ans += (1 << i);
			}
		}

		cout << ans << "\n";
	}
	return 0;
}
T3
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+10, E = 2 * N;
typedef long long ll;
struct node{
	ll a, b;
	friend bool operator <(const node& x, const node& y){
		return x.a == y.a ? x.b > y.b : x.a < y.a;
	}
};
int n;
node tmp[N];
struct graph{
#define lch(x) e[x].ls
#define rch(x) e[x].rs
#define ldis(x) e[x].dl
#define rdis(x) e[x].dr
	struct edge{
		int nxt, to, val;
	}t[E];
	struct tege{
		int ls, rs;
		ll dl, dr;
	}e[E];
	int head[N], elen;
	void inse(int frm, int to, int val){
		t[++elen] = {head[frm], to, val};
		head[frm] = elen;
	}
	void insf(int u, int v, int val){
		inse(u, v, val);
		inse(v, u, val);
	}
	void add(int u, int v, int val){
		if(lch(u)){
			rch(u) = v;
			rdis(u) = val;
		}else{
			lch(u) = v;
			ldis(u) = val;
		}
	}
	void pre_dfs(int u, int fa){
		for(int i = head[u];i ;i = t[i].nxt){
			int v = t[i].to;
			if(v == fa) continue;
			pre_dfs(v, u);
			add(u, v, t[i].val);
		}
	}
	set<node> s[N];
	void dfs(int u, ll mid){
		s[u].clear();
		if(!e[u].ls) {
			s[u].insert({0, 0}); return;
		}
		if(!e[u].rs) {
			int ld = ldis(u);
			dfs(lch(u), mid);
			for(auto x : s[lch(u)]){
				s[u].insert({x.a + ld, x.b + ld});
			}
			return;
		}
		int lson = lch(u), rson = rch(u);
		dfs(lch(u), mid);
		if(s[lch(u)].empty()) return;
		dfs(rch(u), mid);
		if(s[rch(u)].empty()) return;
		int tot = 0;
		ll ld = ldis(u), rd = rdis(u);
		auto ed2 = prev(s[rch(u)].end()), ed1 = s[lch(u)].end();
		for(auto it1 = s[lch(u)].begin(), it2 = s[rch(u)].begin(); it1 != ed1; ++it1){
			while(it2 !=  ed2 && it1 -> b + next(it2) -> a +ld+rd<=mid) ++it2;
			if(it1 -> b + it2 -> a +ld+rd<=mid) tmp[++tot] = {it1->a + ld, it2->b + rd};
		}
		ed2 = prev(s[lch(u)].end());
		ed1 = s[rch(u)].end();
		for(auto it1 = s[rch(u)].begin(), it2 = s[lch(u)].begin(); it1 != ed1; ++it1){
			while(it2 != ed2 && it1 -> b + next(it2) -> a +ld+rd<=mid) ++it2;
			if(it1 -> b + it2 -> a +ld+rd<=mid) tmp[++tot] = {it1->a + rd, it2->b + ld};
		}
		sort(tmp + 1, tmp + 1 + tot);
		if(tot == 0) return;
		s[u].insert(tmp[1]);
		int lst = 1;
		for(int i = 2; i <= tot; ++i){
			if(tmp[i].b < tmp[lst].b){
				s[u].insert(tmp[i]);
				lst = i;
			}
		}
	}
	void prt(){
		for(int i = 1; i <= n; ++i){
			cerr<<"son of" <<i << " ";
			cerr<<lch(i) <<" " << rch(i) << endl;
		}
	}
}G;
bool check(ll mid){
	// for(int i = 1; i <= n; ++i) G.s[i].clear();
	G.dfs(1, mid);
	return G.s[1].size();
}
int main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n;
	for(int i = 1; i < n;++i){
		int u, v;
		cin >> u >> v;
		G.insf(i + 1, u, v);
	}
	G.pre_dfs(1, 0);
	ll l = 0, r = 17179869184ll;
	ll ans = r;
	while(l <= r){
		ll mid = (l + r) >> 1;
		if(check(mid)){
			ans = mid;
			r = mid - 1;
		}else{
			l = mid + 1;
		}
	}
	cout << ans << endl;
	return 0;
}
T4fake
#include<bits/stdc++.h>
using namespace std;
typedef bitset<6> bin;
const int N = 1e2+10, K = 15;
const int INF = 0x3f3f3f3f;
// const int E = 
int mp[N][N];
int f[(1 << 10) + 5];
int d1[(1 <<10) + 5][(1 << 10) + 5];
int d2[K][(1 << 10) + 5];
int lg_[(1 << 20) + 5];
int n, m, k;
int lowbit(int x){
	return x & -x;
}
int ord[K];
int main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	memset(mp, 0x3f, sizeof(mp));
	cin >> n >> m >> k;
	for(int i = 0; i <= k; ++i) lg_[1 << i] = i + 1;
	for(int i = 1; i <= m; ++i){
		int u,v , w;
		cin >> u >> v >> w;
		mp[v][u] = mp[u][v] = min(mp[u][v], w);
	}
	for(int i = 1; i <= n; ++i) mp[i][i] =0 ;
	for(int k = 1; k <= n; ++k){
		for(int i = 1; i <= n; ++i){
			for(int j = 1; j <= n; ++j){
				mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
			}
		}
	}
	for(int i = 1; i <= k; ++i) cin >> ord[i];
	memset(d2, 0x3f, sizeof(d2));
	for(int i = 1; i <= k; ++i){
		int u = ord[i];
		for(int s = 0; s < (1 << k); ++s){
			for(int p = s; p; p -= lowbit(p)){
				int v = ord[lg_[lowbit(p)]];
				d2[i][s] = min(d2[i][s], mp[u][v]);
			}
		}
	}
	memset(d1, 0x3f, sizeof(d1));
	for(int s = 0; s < (1 << k); ++s){
		for(int t = 0; t < (1 << k); ++t){
			if(s & t){
				d1[s][t] = 0;
				continue;
			}
			for(int p = s; p; p -= lowbit(p)){
				d1[s][t] = min(d1[s][t], d2[lg_[lowbit(p)]][t]);
			}
		}
	}
	memset(f, 0x3f, sizeof(f));
	for(int s = 0; s < (1 << k); ++s){
		for(int u = 1; u <= n; ++u){
			int sum = 0;
			for(int p = s; p; p -= lowbit(p)){
				int v = ord[lg_[lowbit(p)]];
				sum = sum + mp[u][v];
			}
			f[s] = min(f[s], sum);
		}
	}
	for(int s = 0; s < (1 << k); ++ s){
		for(int p = s; p; p = (p -1) & s){
			if(p == s) continue;
			f[s] = min(f[s], f[p] + f[s ^ p] + d1[p][s ^ p]);
		}
	}
	cout << f[(1 << k) - 1] << endl;
	return 0;
}
posted @ 2022-09-09 16:46  CDsidi  阅读(17)  评论(0编辑  收藏  举报