zoukankan      html  css  js  c++  java
  • 2020 Multi-University Training Contest 2

    Contest Info


    传送门

    Solved A B C D E F G H I J K L
    7 / 12 O - - - Ø O Ø - Ø O - Ø
    • O 在比赛中通过
    • Ø 赛后通过
    • ! 尝试了但是失败了
    • - 没有尝试

    Solutions


    A. Total Eclipse

    是个假题。。直接并查集倒着做就行。

    Code
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 100007
    #define MAXM 200007
    int b[MAXN];
    int hd[MAXN], nxt[MAXM], to[MAXM], en=0;
    int d[MAXN];
    int mv[MAXN], fa[MAXN];
    inline void adde(int a, int b) {
        nxt[en]=hd[a]; hd[a]=en; to[en]=b; en++;
    }
    inline bool cmp(int x, int y) {
        return b[x]>b[y];
    }
    inline int findfa(int x) {
        int f=x; int v;
        while(fa[f]!=f) f=fa[f];
        v=mv[f];
        while(f!=x) {
            int t=fa[x];
            mv[x]=v;
            fa[x]=f;
            x=t;
        }
        return f;
    }
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
        int T; cin>>T;
        while(0<T--) {
            en=0;
            int n,m; cin>>n>>m;
            for(int i=1; i<=n; i++) cin>>b[i];
            for(int i=1; i<=n; i++) mv[i]=b[i];
            for(int i=1; i<=n; i++) d[i]=i;
            for(int i=1; i<=n; i++) fa[i]=i;
            memset(hd+1,-1,sizeof(int)*n);
            for(int i=0; i<m; i++) {
                int u,v; cin>>u>>v;
                if(b[u]>b[v]) swap(u,v);
                adde(u,v);
            }
            sort(d+1,d+1+n,cmp);
            long long ans=0;
            for(int j=1; j<=n; j++) {
                int x=d[j];
                for(int i=hd[x]; ~i; i=nxt[i]) {
                    int t=to[i];
                    int f1=findfa(x), f2=findfa(t);
                    ans+=mv[f2]-mv[f1];
                    fa[f1]=f2;
                    mv[f2]=mv[f1];
                }
            }
            for(int x=1; x<=n; x++) {
                int f=findfa(x);
                ans+=mv[f]; mv[f]=0;
            }
            cout<<ans<<'
    ';
        }
    }
    

    E. New Equipments

    每一个二次曲线都有一个最优解取值范围,我们对于每个左边的点连接(geq n)个“较优解”,根据hall定理一定存在完美匹配。
    之后直接暴力冲费用流就行。

    Code
    // Author : heyuhhh
    // Created Time : 2020/07/23 22:39:10
    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 5000 + 5, M = 50000 + 5;
    
    struct E {
        int from, to, cp;
        ll v;
        E() {}
        E(int f, int t, int cp, ll v) : from(f), to(t), cp(cp), v(v) {}
    };
    
    ll f[N];
    
    struct MCMF {
        int n, m, s, t;
        vector<E> edges;
        vector<int> G[N];
        bool inq[N];
        ll d[N];
        int p[N], a[M];
    
        void init(int _n, int _s, int _t) {
            n = _n; s = _s; t = _t;
            for(int i = 0; i <= n; i++) G[i].clear();
            edges.clear(); m = 0;
        }
    
        void addedge(int from, int to, int cap, ll cost) {
            edges.emplace_back(from, to, cap, cost);
            edges.emplace_back(to, from, 0, -cost);
            G[from].push_back(m++);
            G[to].push_back(m++);
        }
    
        bool BellmanFord(int &flow, ll &cost) {
            for(int i = 0; i <= n; i++) d[i] = 6e18;
            memset(inq, 0, sizeof inq);
            d[s] = 0, a[s] = INF, inq[s] = true;
            queue<int> Q; Q.push(s);
            while (!Q.empty()) {
                int u = Q.front(); Q.pop();
                inq[u] = false;
                for (int& idx: G[u]) {
                    E &e = edges[idx];
                    if (e.cp && d[e.to] > d[u] + e.v) {
                        d[e.to] = d[u] + e.v;
                        p[e.to] = idx;
                        a[e.to] = min(a[u], e.cp);
                        if (!inq[e.to]) {
                            Q.push(e.to);
                            inq[e.to] = true;
                        }
                    }
                }
            }
            if (d[t] == 6e18) return false;
            flow += a[t];
            cost += 1ll * a[t] * d[t];
            int u = t;
            while (u != s) {
                edges[p[u]].cp -= a[t];
                edges[p[u] ^ 1].cp += a[t];
                u = edges[p[u]].from;
            }
            return true;
        }
    
        ll go() {
            int flow = 0;
            ll cost = 0;
            int t = 0;
            while (BellmanFord(flow, cost)) {
                f[++t] = cost;
            }
            return cost;
        }
    } MM;
    
    int a[N], b[N];
    ll c[N];
    int n, m;
    
    void run() {
        map<int, int> mp;
        cin >> n >> m;
        int tot = n;
        for (int i = 1; i <= n; i++) {
            cin >> a[i] >> b[i] >> c[i];
            if (b[i] >= 0) {
                for (int j = 1; j <= min(m, n + 1); j++) {
                    if (mp.find(j) == mp.end()) {
                        mp[j] = ++tot;
                    }
                }
            } else {
                int t = - b[i] / (2 * a[i]);
                for (int j = max(t - n, 1); j <= min(m, t + n); j++) {
                    if (mp.find(j) == mp.end()) {
                        mp[j] = ++tot;
                    }
                }
            }
        }
        MM.init(tot + 1, 0, tot + 1);
        for (int i = 1; i <= n; i++) {
            MM.addedge(0, i, 1, 0);
        }
        for (auto& it : mp) {
            MM.addedge(it.se, tot + 1, 1, 0);
        }
        for (int i = 1; i <= n; i++) {
            if (b[i] >= 0) {
                for (int j = 1; j <= min(m, n + 1); j++) {
                    MM.addedge(i, mp[j], 1, 1ll * a[i] * j * j + 1ll * b[i] * j + c[i]);
                }
            } else {
                int t = - b[i] / (2 * a[i]);
                for (int j = max(t - n, 1); j <= min(m, t + n); j++) {
                    MM.addedge(i, mp[j], 1, 1ll * a[i] * j * j + 1ll * b[i] * j + c[i]);
                }
            }
        }
        MM.go();
        for (int i = 1; i <= n; i++) {
            cout << f[i] << " 
    "[i == n];
        }
    }
    int main() {
    #ifdef Local
        freopen("input.in", "r", stdin);
    #endif
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    F. The Oculus

    题意:
    给出(A,B,C),每个数都用斐波纳契数列来表示,即(x=a_1cdot F_1+a_2cdot F_2+cdots+a_ncdot F_n,a_iin{0,1})
    现有(Acdot B=C),但(C)会有一个(1)变为了(0),所以现在就要找到哪一个位置变为了(0)

    思路:
    直接做是不好做的,并没有什么比较好用的性质能够套在这题上面。
    对于这种不需要知道精确解的问题,其实可以用hash来判断大小、相等关系。这是一个比较常见的思路。
    所以就直接上hash就行。。

    Code
    // Author : heyuhhh
    // Created Time : 2020/07/23 16:24:33
    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 2e6 + 5;
    const int p[3] = {998244353, 100000259, 10001093};
    
    #define FI(n) FastIO::read(n)
    #define FO(n) FastIO::write(n)
    #define Flush FastIO::Fflush()
    namespace FastIO {
        const int SIZE = 1 << 16;
        char buf[SIZE], obuf[SIZE], str[60];
        int bi = SIZE, bn = SIZE, opt;
        double D[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001};
        int read(char *s) {
            while (bn) {
                for (; bi < bn && buf[bi] <= ' '; bi++);
                if (bi < bn) break;
                bn = fread(buf, 1, SIZE, stdin);
                bi = 0;
            }
            int sn = 0;
            while (bn) {
                for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
                if (bi < bn) break;
                bn = fread(buf, 1, SIZE, stdin);
                bi = 0;
            }
            s[sn] = 0;
            return sn;
        }
        bool read(int& x) {
            int n = read(str), bf = 0;
            if (!n) return 0;
            int i = 0; if (str[i] == '-') bf = 1, i++; else if (str[i] == '+') i++;
            for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
            if (bf) x = -x;
            return 1;
        }
        bool read(long long& x) {
            int n = read(str), bf;
            if (!n) return 0;
            int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
            for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
            if (bf < 0) x = -x;
            return 1;
        }
        void write(int x) {
            if (x == 0) obuf[opt++] = '0';
            else {
                if (x < 0) obuf[opt++] = '-', x = -x;
                int sn = 0;
                while (x) str[sn++] = x % 10 + '0', x /= 10;
                for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
            }
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
        void write(long long x) {
            if (x == 0) obuf[opt++] = '0';
            else {
                if (x < 0) obuf[opt++] = '-', x = -x;
                int sn = 0;
                while (x) str[sn++] = x % 10 + '0', x /= 10;
                for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
            }
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
        void write(unsigned long long x) {
            if (x == 0) obuf[opt++] = '0';
            else {
                int sn = 0;
                while (x) str[sn++] = x % 10 + '0', x /= 10;
                for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
            }
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
        void write(char x) {
            obuf[opt++] = x;
            if (opt >= (SIZE >> 1)) {
                fwrite(obuf, 1, opt, stdout);
                opt = 0;
            }
        }
        void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt = 0;}
    };
    
    int fib[N][3];
    
    void init() {
        fib[1][0] = fib[1][1] = fib[1][2] = 1;
        fib[2][0] = fib[2][1] = fib[2][2] = 2;
        for (int k = 0; k < 3; k++) {
            for (int i = 3; i < N; i++) {
                fib[i][k] = (fib[i - 1][k] + fib[i - 2][k]) % p[k];
            }
        }
    }
    
    int a[N], b[N], c[N];
    int sa[3], sb[3], sc[3];
    
    void run() {
        for (int k = 0; k < 3; k++) {
            sa[k] = sb[k] = sc[k] = 0;
        }
        int na, nb, nc;
        FI(na);
        for (int i = 1; i <= na; i++) {
            FI(a[i]);
            for (int k = 0; k < 3; k++) {
                if (a[i]) {
                    sa[k] = (sa[k] + fib[i][k]) % p[k];
                }
            }
        }
        FI(nb);
        for (int i = 1; i <= nb; i++) {
            FI(b[i]);
            for (int k = 0; k < 3; k++) {
                if (b[i]) {
                    sb[k] = (sb[k] + fib[i][k]) % p[k];
                }
            }
        }
        FI(nc);
        for (int i = 1; i <= nc; i++) {
            FI(c[i]);
            for (int k = 0; k < 3; k++) {
                if (c[i]) {
                    sc[k] = (sc[k] + fib[i][k]) % p[k];
                }
            }
        }
        map<int, int> mp;
        for (int k = 0; k < 3; k++) {
            int t = (1ll * sa[k] * sb[k] % p[k] - sc[k] + p[k]) % p[k];
            for (int i = 1; i < nc; i++) {
                if (fib[i][k] == t) {
                    ++mp[i];
                    if (mp[i] == 3) {
                        FO(i), FO('
    ');
                        return;
                    }
                }
            }
        }
    }
    int main() {
    #ifdef Local
        freopen("input.in", "r", stdin);
    #endif
        init();
        int T; cin >> T; while(T--)
        run();
        Flush;
        return 0;
    }
    

    G. In Search of Gold

    二分一下直径然后树形dp判断是否可行即可,类似于树上背包的问题,注意加上减枝,即对size取min,这样复杂度可以做到(O(nklog(ans)))

    Code
    // Author : heyuhhh
    // Created Time : 2020/07/24 10:09:05
    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 20000 + 5, M = 25;
    
    int n, k;
    struct Edge {
        int v, next, a, b;
    }e[N << 1];
    int head[N], tot;
    void adde(int u, int v, int a, int b) {
        e[tot] = Edge{v, head[u], a, b};
        head[u] = tot++;
    }
    
    #define FI(n) FastIO::read(n)
    #define FO(n) FastIO::write(n)
    #define Flush FastIO::Fflush()
    namespace FastIO {
    	const int SIZE = 1 << 16;
    	char buf[SIZE], obuf[SIZE], str[60];
    	int bi = SIZE, bn = SIZE, opt;
    	double D[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001};
    	int read(char *s) {
    		while (bn) {
    			for (; bi < bn && buf[bi] <= ' '; bi++);
    			if (bi < bn) break;
    			bn = fread(buf, 1, SIZE, stdin);
    			bi = 0;
    		}
    		int sn = 0;
    		while (bn) {
    			for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
    			if (bi < bn) break;
    			bn = fread(buf, 1, SIZE, stdin);
    			bi = 0;
    		}
    		s[sn] = 0;
    		return sn;
    	}
    	bool read(int& x) {
    		int n = read(str), bf = 0;
    		if (!n) return 0;
    		int i = 0; if (str[i] == '-') bf = 1, i++; else if (str[i] == '+') i++;
    		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
    		if (bf) x = -x;
    		return 1;
    	}
    	bool read(long long& x) {
    		int n = read(str), bf;
    		if (!n) return 0;
    		int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
    		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
    		if (bf < 0) x = -x;
    		return 1;
    	}
    	void write(int x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			if (x < 0) obuf[opt++] = '-', x = -x;
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(long long x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			if (x < 0) obuf[opt++] = '-', x = -x;
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(unsigned long long x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(char x) {
    		obuf[opt++] = x;
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt = 0;}
    };
    
    ll dp[N][M], t[M];
    int sz[N];
    bool flag;
    
    void dfs(int u, int fa, ll x) {
        if (flag) return;
        sz[u] = 1;
        dp[u][0] = 0;
        for (int i = head[u]; i != -1; i = e[i].next) {
            int v = e[i].v, a = e[i].a, b = e[i].b;
            if (v == fa) continue;
            dfs(v, u, x);
            if (flag) return;
            int up = min(sz[u] + sz[v] - 1, k);
            for (int j = 0; j <= up; j++) {
                t[j] = x + 1;
            }
            for (int j = 0; j < sz[u]; j++) {
                for (int p = 0; p < sz[v] && p + j <= up; p++) {
                    if (dp[u][j] + dp[v][p] + b <= x) {
                        t[j + p] = min(t[j + p], max(dp[u][j], dp[v][p] + b));
                    }
                    if (dp[u][j] + dp[v][p] + a <= x) {
                        t[j + p + 1] = min(t[j + p + 1], max(dp[u][j], dp[v][p] + a));
                    }
                }
            }
            sz[u] += sz[v];
            bool ok = false;
            for (int j = 0; j <= up; j++) {
                dp[u][j] = t[j];
                if (t[j] <= x) ok = true;
            }
            if (ok = false) {
                dp[1][k] = x + 1;
                flag = true;
                return;
            }
        }
    }
    
    void run() {
        FI(n), FI(k);
        for (int i = 1; i <= n; i++) {
            head[i] = -1;
        }
        tot = 0;
        ll l = 1, r = 2, mid;
        for (int i = 1; i < n; i++) {
            int u, v, a, b;
            FI(u), FI(v), FI(a), FI(b);
            r += max(a, b);
            adde(u, v, a, b);
            adde(v, u, a, b);
        }
        while (l < r) {
            mid = (l + r) >> 1;
            flag = false;
            dfs(1, 0, mid);
            if (dp[1][k] <= mid) r = mid;
            else l = mid + 1;
        }
        FO(l), FO('
    ');
    }
    int main() {
    #ifdef Local
        freopen("input.in", "r", stdin);
    #endif
        int T; FI(T); while(T--)
        run();
        Flush;
        return 0;
    }
    

    I. It's All Squares

    发现暴力似乎可以过。。那就暴力吧。。

    Code
    // Author : heyuhhh
    // Created Time : 2020/07/24 19:03:09
    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 400 + 5;
    
    #define FI(n) FastIO::read(n)
    #define FO(n) FastIO::write(n)
    #define Flush FastIO::Fflush()
    namespace FastIO {
    	const int SIZE = 1 << 16;
    	char buf[SIZE], obuf[SIZE], str[60];
    	int bi = SIZE, bn = SIZE, opt;
    	double D[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001};
    	int read(char *s) {
    		while (bn) {
    			for (; bi < bn && buf[bi] <= ' '; bi++);
    			if (bi < bn) break;
    			bn = fread(buf, 1, SIZE, stdin);
    			bi = 0;
    		}
    		int sn = 0;
    		while (bn) {
    			for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
    			if (bi < bn) break;
    			bn = fread(buf, 1, SIZE, stdin);
    			bi = 0;
    		}
    		s[sn] = 0;
    		return sn;
    	}
    	bool read(int& x) {
    		int n = read(str), bf = 0;
    		if (!n) return 0;
    		int i = 0; if (str[i] == '-') bf = 1, i++; else if (str[i] == '+') i++;
    		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
    		if (bf) x = -x;
    		return 1;
    	}
    	bool read(long long& x) {
    		int n = read(str), bf;
    		if (!n) return 0;
    		int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
    		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
    		if (bf < 0) x = -x;
    		return 1;
    	}
    	void write(int x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			if (x < 0) obuf[opt++] = '-', x = -x;
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(long long x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			if (x < 0) obuf[opt++] = '-', x = -x;
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(unsigned long long x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(char x) {
    		obuf[opt++] = x;
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt = 0;}
    };
    
    int n, m, q;
    int w[N][N];
    int tag[N][N];
    int cnt[N * N];
    char s[4000000 + 5];
    
    void run() {
        FI(n), FI(m), FI(q);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                FI(w[i][j]);
                cnt[w[i][j]] = -1;
            }
        }
        while (q--) {
            int sx, sy;
            FI(sx), FI(sy);
            FI(s);
            int len = strlen(s);
            int L = m + 1, R = 0, D = n + 1, U = 0;
            int x = sx, y = sy;
            for (int i = 0; i < len; i++) {
                L = min(L, x);
                R = max(R, x);
                D = min(D, y);
                U = max(U, y);
                if (s[i] == 'L') --x;
                if (s[i] == 'R') ++x;
                if (s[i] == 'D') --y;
                if (s[i] == 'U') ++y;
            }
            ++L, ++D;
            assert(D <= U && L <= R);
            for (int i = L; i <= R; i++) {
                for (int j = D; j <= U; j++) {
                    tag[i][j] = 0;
                }
            }
            x = sx, y = sy;
            for (int i = 0; i < len; i++) {
                if (s[i] == 'R') {
                    ++x;
                    tag[x][y + 1] = 1;
                }
                if (s[i] == 'L') {
                    tag[x][y + 1] = 1;
                    --x;
                }
                if (s[i] == 'D') {
                    --y;
                }
                if (s[i] == 'U') {
                    ++y;
                }
            }
            int ans = 0;
            for (int i = L; i <= R; i++) {
                int op = 0;
                for (int j = D; j <= U; j++) {
                    op ^= tag[i][j];
                    if (op) {
                        if (cnt[w[i][j]] != q) {
                            cnt[w[i][j]] = q;
                            ++ans;
                        }
                    }
                }
            }
    
            FO(ans), FO('
    ');
        }
    }
    int main() {
        int T; cin >> T; while(T--)
        run();
        Flush;
        return 0;
    }
    

    J. Lead of Wisdom

    直接爆搜。

    Code
    // Author : heyuhhh
    // Created Time : 2020/07/23 12:57:36
    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 50 + 5;
    
    #define FI(n) FastIO::read(n)
    #define FO(n) FastIO::write(n)
    #define Flush FastIO::Fflush()
    namespace FastIO {
    	const int SIZE = 1 << 16;
    	char buf[SIZE], obuf[SIZE], str[60];
    	int bi = SIZE, bn = SIZE, opt;
    	double D[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001};
    	int read(char *s) {
    		while (bn) {
    			for (; bi < bn && buf[bi] <= ' '; bi++);
    			if (bi < bn) break;
    			bn = fread(buf, 1, SIZE, stdin);
    			bi = 0;
    		}
    		int sn = 0;
    		while (bn) {
    			for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
    			if (bi < bn) break;
    			bn = fread(buf, 1, SIZE, stdin);
    			bi = 0;
    		}
    		s[sn] = 0;
    		return sn;
    	}
    	bool read(int& x) {
    		int n = read(str), bf = 0;
    		if (!n) return 0;
    		int i = 0; if (str[i] == '-') bf = 1, i++; else if (str[i] == '+') i++;
    		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
    		if (bf) x = -x;
    		return 1;
    	}
    	bool read(long long& x) {
    		int n = read(str), bf;
    		if (!n) return 0;
    		int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
    		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
    		if (bf < 0) x = -x;
    		return 1;
    	}
    	void write(int x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			if (x < 0) obuf[opt++] = '-', x = -x;
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(long long x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			if (x < 0) obuf[opt++] = '-', x = -x;
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(unsigned long long x) {
    		if (x == 0) obuf[opt++] = '0';
    		else {
    			int sn = 0;
    			while (x) str[sn++] = x % 10 + '0', x /= 10;
    			for (int i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
    		}
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void write(char x) {
    		obuf[opt++] = x;
    		if (opt >= (SIZE >> 1)) {
    			fwrite(obuf, 1, opt, stdout);
    			opt = 0;
    		}
    	}
    	void Fflush() { if (opt) fwrite(obuf, 1, opt, stdout); opt = 0;}
    };
    
    int n, k;
    int a[N], b[N], c[N], d[N];
    int type[N][N];
    int num[N];
    int sa, sb, sc, sd;
    
    ll ans;
    
    void dfs(int cur) {
        if (cur == 0) {
            ans = max(ans, 1ll * sa * sb * sc * sd);
            return;
        }
        int prea, preb, prec, pred;
        prea = preb = prec = pred = -1;
        if (num[cur]) for (register int i = 1; i <= num[cur]; ++i) {
            int id = type[cur][i];
            sa += a[id], sb += b[id], sc += c[id], sd += d[id];
            if (prea == -1) {
                prea = sa;
                preb = sb;
                prec = sc;
                pred = sd;
                dfs(cur - 1);
            } else {
                if (sa <= prea && sb <= preb && sc <= prec && sd <= pred) {
                } else {
                    dfs(cur - 1);
                }
                prea = min(prea, sa);
                preb = min(preb, sb);
                prec = min(prec, sc);
                pred = min(pred, sd);
            }
            sa -= a[id], sb -= b[id], sc -= c[id], sd -= d[id];
        } else {
            dfs(cur - 1);
        }
    }
    
    void run() {
        FI(n), FI(k);
        for (register int i = 1; i <= k; ++i) {
            num[i] = 0;
        }
        ans = 0;
        for (register int i = 1; i <= n; ++i) {
            int t; FI(t);
            FI(a[i]), FI(b[i]), FI(c[i]), FI(d[i]);
            type[t][++num[t]] = i;
        }
        sa = sb = sc = sd = 100;
        dfs(k);
        FO(ans), FO('
    ');
    }
    int main() {
    #ifdef Local
        freopen("input.in", "r", stdin);
    #endif
        int T; FI(T); while(T--)
        run();
        Flush;
        return 0;
    }
    

    L. String Distance

    题意:
    给出两个字符串(S,T),长度分别为(n,m(nleq 10^5,mleq 20)),现在每一次操作都可以在任意一个位置插入或者删除一个字符。
    之后会给出若干组询问,每次询问区间([l_i,r_i]),然后需要回答使得(s)串这一个子串和(t)串相等的最小操作次数为多少。

    思路:
    其实就是要我们求(s_{l,...,r})(t)串的lcs,那么答案就为(r-l+1+m-2cdot lcs)
    那么正常的做法应该为(dp[i][j]):(s)串匹配到了(i)(t)串匹配到了(j)的lcs为多少,但显然这个状态我们不好存储,时间复杂度也会爆炸。
    注意到其实我们只需要check长度为(k)的lcs是否存在,所以换一下dp的方式,(dp[i][j])表示(t)串考虑了前(i)位,长度为(j)的lcs匹配到了(s)串的哪个位置(就相当于换一下状态)。那么之后就是一个(O(m^2))(dp)了。所以总的时间复杂度为(O(nm^2))
    细节见代码:

    Code
    // Author : heyuhhh
    // Created Time : 2020/07/23 20:36:09
    #include<bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5, M = 20 + 5;
    
    char s[N], t[M];
    int n, m;
    int nxt[N][26];
    int dp[M][M];
    
    void run() {
        cin >> (s + 1) >> (t + 1);
        n = strlen(s + 1);
        m = strlen(t + 1);
        for (int i = 0; i < 26; i++) {
            nxt[n][i] = n + 1;
        }
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j < 26; j++) {
                nxt[i][j] = nxt[i + 1][j];
            }
            nxt[i][s[i + 1] - 'a'] = i + 1;
        }
        int q; 
        cin >> q;
        while (q--) {
            int l, r; cin >> l >> r;
            memset(dp, -1, sizeof(dp));
            dp[0][0] = l - 1;
            for (int i = 0; i < m; i++) {
                for (int j = 0; j <= i; j++) {
                    if (dp[i][j] >= 0 && dp[i][j] <= r) {
                        int pos = dp[i][j];
                        int go = nxt[pos][t[i + 1] - 'a'];
                        if (dp[i + 1][j + 1] == -1) {
                            dp[i + 1][j + 1] = go;
                        } else {
                            dp[i + 1][j + 1] = min(dp[i + 1][j + 1], go);
                        }
                        if (dp[i + 1][j] == -1) {
                            dp[i + 1][j] = dp[i][j];
                        } else {
                            dp[i + 1][j] = min(dp[i + 1][j], dp[i][j]);
                        }
                    }
                }
            }
            int ans = r - l + 1 + m;
            for (int i = m; i >= 0; i--) {
                if (dp[m][i] >= l && dp[m][i] <= r) {
                    ans -= 2 * i;
                    break;
                }
            }
            cout << ans << '
    ';
        }
    }
    int main() {
    #ifdef Local
        freopen("input.in", "r", stdin);
    #endif
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    
  • 相关阅读:
    阶乘递归实现
    队列
    1+2+3+...+100用递归实现
    快速排序C语言实现
    js的onfocus,onblur事件
    CSP2021 游记 菜到离谱
    700题复习计划
    [传递闭包] P2881 [USACO07MAR]排名的牛Ranking the Cows
    【笔记】序列分块
    【题解】UVA10930 A-Sequence
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/13375908.html
Copyright © 2011-2022 走看看