美文网首页
题目整理3

题目整理3

作者: TimeMage | 来源:发表于2017-03-18 15:42 被阅读19次
    • CF785D

    计数
    http://codeforces.com/contest/785/problem/D

    题解

    1. 非常有意思的一道题,求一段括号序列中RSBS的个数,但有个关键点必须事先知道不然无法做。
    2. 对于前x个为左括号后y个为右括号的序列,它的RSBS为( x x+y
    1. 若指定某个左括号为RSBS序列最后的左括号,他在原序列中前面有x-1个左括号,后面有y个右括号,则这样的RSBS序列有(xx+y-1)个。
    2. 详情见http://codeforces.com/blog/entry/50996
    3. 1到n n个数的逆元可以O(n)求, 通过(b<sup >a)可以O(1)求(b+1a+1)和(ba-1), 综上复杂度为O(n);

    代码

    #include<cstdio>
    typedef long long ll;
    const int MAXN = 2e5+1e3;
    const int MOD = 1e9+7;
    ll ans = 0, cur;
    ll inv[MAXN];
    char s[MAXN];
    int n, x, y, a;
    int main() {
        scanf("%s", s);
        inv[0] = 0;
        inv[1] = 1;
        for(int i=2; i<MAXN; ++i)
            inv[i] = -inv[MOD%i]*(MOD/i)%MOD;
        x = y = n = 0;
        for(char *p=s; *p; ++p) {
            if(*p==')') ++y;
            ++n;
        }
        a = x+y-1;
        cur = 1;
        for(int i=0; i<n&&y; ++i) {
            if(s[i]=='(') {
                ++a, ++x;
                cur = cur*a%MOD*inv[x]%MOD;
                ans = (ans+cur)%MOD;
            }
            else {
                cur = cur*(a-x)%MOD*inv[a]%MOD;
                --a, --y;
                if(!y) break;
            }
        }
        if(ans<0) ans+=MOD;
        printf("%I64d\n", ans);
        return 0;
    }
    
    • topcoder SRM 710 div2 C

    图论最大最小
    Problem Statement

    You are given an undirected graph with n nodes and m edges. The nodes are labeled from 0 to n-1. This graph is guaranteed to be connected and have no self-loops or multiple edges.
    You are given a description of the graph: the vector <int>s a, b, w, and v. For each valid i, there is an edge that connects nodes a[i] and b[i] and has weight w[i]. For each valid j, node j has weight v[j]. All weights are positive integers.
    A path in this graph is a sequence of pairwise distinct nodes such that each pair of consecutive nodes is connected by an edge. The difficulty of a path is the value (N times E), where N is the maximum weight of a node on the path (including the nodes where it starts and ends) and E is the maximum weight of an edge on the path.
    For each pair of distinct nodes i and j, let d(i,j) be the smallest possible difficulty of a path that connects i and j. Find and return the sum of d(i,j) with 0 ≤ i < j ≤ n-1.
    

    题解:

    有几点
    1.  最大的点值最小的路径不一定与最大边值最小的路径相同
    2.  a到b有多条路径, b到c有1条路,a到b的最优解不一定被包含在a到c的最优解。
    3.  一个解法为,枚举每个点,假设他为路径上点值最大的点,找到点值小于等于他的点,包含他所构成的连通分量,在进行算,复杂度O(n^4).
    

    代码:

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int MAXN = 312;
    typedef pair<int,int> pii;
    int dbg = 0;
    class MinMaxMax
    {
        long long d[MAXN][MAXN];
        int fa[MAXN];
        bool alive[MAXN];
        vector<pii> su, se;
        vector<int> sa, sb;
        int n, m;
    public: 
        int getfa(int x) {
            if(x==fa[x]) return x;
            return fa[x]=getfa(fa[x]);
        }
        long long findMin(vector <int> a, 
                vector <int> b, 
                vector <int> w, 
                vector <int> v) {
            m = a.size();
            n = v.size();
            su.clear();
            se.clear();
            int i, j;
            i=0; for(auto e: w)
                se.push_back(make_pair(e, i++));
            i=0; for(auto u: v)
                su.push_back(make_pair(u, i++));
            sort(su.begin(), su.end());
            sort(se.begin(), se.end());
            memset(d, 0x3f, sizeof(d));
            for(auto u:su) {
                for(i=0; i<n; ++i) fa[i] = i;
                for(auto ui:su)
                    alive[ui.second] = (ui.first<=u.first);
                for(auto e:se) {
                    int s=a[e.second], t=b[e.second];
                    if(!alive[s]||!alive[t]) continue;
                    s=getfa(s); t=getfa(t);
                    if(s==t) continue;
                    sa.clear(); sb.clear();
                    for(i=0; i<=n; ++i) {
                        if(getfa(i)==s) sa.push_back(i);
                        else if(getfa(i)==t) sb.push_back(i);
                    }
                    long long cur = 1ll*e.first*u.first;
                    for(auto ai:sa)
                        for(auto bi:sb) {
                            d[ai][bi] = min(d[ai][bi], cur);
                            d[bi][ai] = min(d[bi][ai], cur);
                        }
                    fa[s] = fa[t] = min(s,t);
                }
            }
            long long ret = 0;
            for(i=0; i<n; ++i)
                for(j=i+1; j<n; ++j)
                    ret += d[i][j];
            return ret;
        }
    };
    

    FZU-2128

    AC自动机
    https://vjudge.net/problem/FZU-2128
    题解: 上个月做的一道AC自动机的模板题,主要是做个整理

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    const int MAXL = 1<<20;
    const int MAXN = 1e5+1e3;
    char s[MAXL];
    vector<pair<int,int> > v;
    struct Trie{
        int ch[MAXN][26];
        int val[MAXN], sz;
        int last[MAXN], f[MAXN];
        void clear() {
            sz = 1;
            memset(ch[0], 0, sizeof(ch[0]));
        }
        int idx(char c) {
            return c-'a';
        } 
        void insert(char* s) {
            int u = 0, i;
            for(i=0; s[i]; ++i) {
                int c= idx(s[i]);
                if(!ch[u][c]) {
                    memset(ch[sz], 0, sizeof(ch[sz]));
                    val[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] = i;
        }
        void print(int ed, int j) {
            if(j) {
                v.push_back(make_pair(ed-val[j]+1, ed));
                print(ed, last[j]);
            }
        } 
        void find(char* T) {
            int l = strlen(T);
            int j = 0;
            for(int i=0; i<l; ++i) {
                int c = idx(T[i]);
                while(j&&!ch[j][c]) j=f[j];
                j = ch[j][c];
    
                if(val[j]) print(i,j);
                else if(last[j]) print(i, last[j]);
            }   
        }
        void getFail() {
            queue<int> q;
            f[0] = 0;
            for(int c=0; c<26; ++c) {
                int u = ch[0][c];
                if(u) {
                    f[u] = last[u] = 0;
                    q.push(u);
                }
            }
            while(!q.empty()) {
                int r = q.front(); q.pop();
                for(int c=0; c<26; ++c) {
                    int u = ch[r][c];
                    if(!u) continue;
                    q.push(u);
                    int v = f[r];
                    while(v&&!ch[v][c]) v=f[v];
                    f[u] = ch[v][c];
                    last[u] = val[f[u]]?f[u]:last[f[u]];
                }
            }
        }
    }AC;
    int main() {
        ios::sync_with_stdio(false);
        while(cin >> s) {
            char tmp[128];
            int n, len;
            len = strlen(s);
            cin >> n;
            AC.clear();
            for(int i=0; i<n; ++i) {
                cin >> tmp;
                AC.insert(tmp);
            }
            AC.getFail();
            v.clear();
            AC.find(s);
            sort(v.begin(), v.end());
            int l = 0, ans=0;
            for(int i=0; i<v.size(); ++i) {
                ans = max(ans,v[i].second-l);
                l = v[i].first+1;
            }
            ans = max(ans, len-l);
            cout << ans << endl;
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:题目整理3

          本文链接:https://www.haomeiwen.com/subject/ornunttx.html