题目整理3

  • 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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 一位朋友曾这么感叹自己的妈妈:她最不值得了,一生为子女操劳,却吃力不讨好。到最后,连她自己都说,没有人会喜欢她。 ...
    凌星虹阅读 479评论 1 12
  • 早春的天气,多大风。艳阳,天空澄蓝,无云。傍晚时,开车经过老码头,被半边天火红的颜色吸引,那是一轮巨大的即将归隐的...
    悠游四海阅读 348评论 6 3