Edu 67 补题记录

CF1187D. Subarray Sorting 

想要把一个数x换到前面,x一定是小一点的值。由于B串是固定的,A串可调整,我们可以遍历B数组,对于B【i】,找到对于在A数组的位子pos,判断1~pos中,是不是A【pos】最小,如果是最小,说明可以换到最前面,把A【pos】的值变为inf后,继续遍历。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int inf = 0x3f3f3f3f;
 
const int MOD = 1e9+7;
 
/**********showtime************/
 
            const int maxn = 3e5+9;
            int a[maxn], b[maxn];
            queue<int>que[maxn];
            int mn[maxn<<2];
            void update(int pos, int val, int le, int ri, int rt) {
                if(le == ri) {
                    mn[rt] = val;
                    return ;
                }
                int mid = (le + ri) >> 1;
                if(mid >= pos) update(pos, val, le, mid, rt<<1);
                else update(pos, val, mid+1, ri, rt<<1|1);
                mn[rt] = min(mn[rt<<1], mn[rt<<1|1]);
            }
            int query(int L, int R, int le, int ri, int rt) {
                if(le >= L && ri <= R) {
                    return mn[rt];
                }
                int mid = (le + ri) >> 1;
                int res = inf;
                if(mid >= L) res = min(res, query(L,R,le, mid, rt<<1));
                if(mid < R) res = min(res, query(L,R,mid+1, ri, rt<<1|1));
                return res;
            }
            void build(int le, int ri, int rt) {
                if(le == ri) return ;
                int mid = (le + ri) >> 1;
                build(le, mid, rt<<1);
                build(mid+1, ri, rt<<1|1);
            }
int main(){
            int T;  scanf("%d", &T);
            while(T--) {
                int n;  scanf("%d", &n);
                build(1, n, 1);
                for(int i=1; i<=n; i++) scanf("%d", &a[i]), que[a[i]].push(i), update(i, a[i], 1, n, 1);
                for(int i=1; i<=n; i++) scanf("%d", &b[i]);
                int flag = 1;
                for(int i=1; i<=n; i++) {
                    if(!que[b[i]].empty()) {
                        int p = que[b[i]].front();  que[b[i]].pop();
                        if(query(1, p, 1, n, 1) < b[i]) flag = 0;
                        else update(p, inf, 1, n, 1);
                    }
                    else flag = 0;
                }
                for(int i=1; i<=n; i++) {
                    while(!que[a[i]].empty()) que[a[i]].pop();
                }
                puts(flag?"YES":"NO");
            }
            return 0;
}
View Code

E Tree Painting

树形DP,换根的转移。

#include <bits/stdc++.h>
 
using namespace std;
 
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
 
 
 
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x7f7f7f7f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-6;
/**********showtime************/
            const int maxn = 2e5+9;
            vector<int> mp[maxn];
            int sz[maxn];
            ll ans = 0;
            int n;
            void dfs(int u, int fa) {
                sz[u] = 1;
                for(int i=0; i<mp[u].size(); i++) {
                    int v = mp[u][i];
                    if(v == fa) continue;
                    dfs(v, u);
                    sz[u] += sz[v];
                }
                ans += sz[u];
            }
            void dfs2(int u, int fa, ll pre) {
 
                for(int i=0; i<mp[u].size(); i++) {
                    int v = mp[u][i];
                    if(v == fa) continue;
 
                    ll tmp = pre + n - 2ll * sz[v];
                    ans = max(ans, tmp);
 
                    dfs2(v, u, tmp);
                }
            }
int main(){
            scanf("%d", &n);
            for(int i=1; i<n; i++) {
                int u,v;
                scanf("%d%d", &u, &v);
                mp[u].pb(v);
                mp[v].pb(u);
            }
            dfs(1, -1);
            dfs2(1, -1, ans);
            printf("%lld\n", ans);
            return 0;
}
View Code

G Gang Up

网络流,待补

猜你喜欢

转载自www.cnblogs.com/ckxkexing/p/11117214.html
67