51nod 模拟4
对本次分数的预测:
基本分 \(160\)
平均分\(\leq 100\)
T1, T3 AC人数 \(\leq2\)
至少AC一道题的人数 \(\leq10\)
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;
}