码迷,mamicode.com
首页 > 其他好文 > 详细

str2int

时间:2018-09-04 13:46:41      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:状态   组成   学生   需要   amp   单个字符   nod   重复   node   

#str2int

这道题是我在紫本上看到的,luogu上也有这道题

题目描述:

技术分享图片

题目大意:输入n个由0-9组成的字符串,然后把所有字符串的所有连续子串提出来化为integer,接着去掉重复的integer.最后,求这些integers的和除以2011的余数.

紫书上的分析:其实每个状态里的字符串集就是不同的子串集合.但是这儿有两个问题:第一,本题的字符串有多个,但是DAWG是针对单个字符串的;第二,因为有零的存在两个不同子串可能对应同一整数.

需要注意的是:因为字符串的总长度较大,最好先对DAWG各个状态进行拓扑排序,再递推,而不要直接进行记忆化搜索,不然会栈溢出.

AC代码:

#include <bits/stdc++.h>
using namespace std;

struct DAWG{
    struct Node{
        Node *fa, *next[11];
        int len;
        int id, pos;
        Node(){}
        Node(int len):fa(0),len(len){
            memset(next, 0, sizeof(next));
        }
    };
    Node node[100010*2], *root, *last;
    int tot;
    Node *newnode(const Node& u){
        node[tot] = u;
        node[tot].id = tot;
        return &node[tot++];
    }
    Node* newnode(int len){ return newnode(Node(len)); }
    Node* newnode(Node *p){ return newnode(*p); }

    void init(){
        tot = 0;
        root = last = newnode(0);
        node[0].pos = 0;
    }

    void add(int x,int len){
        Node *p = last, *np = newnode(p->len + 1);
        np->pos = len;
        last = np;
        for(; p && !p->next[x];p = p->fa) p->next[x] = np;
        if(!p) { np->fa = root; return; }
        Node *q = p->next[x];
        if(q->len == p->len + 1){ np->fa = q; return; }
        Node *nq = newnode(q);
        nq->len = p->len + 1;
        q->fa = nq;
        np->fa = nq;
        for(; p && p->next[x] == q; p = p->fa) p->next[x] = nq;
    }
};

char s[100010];
int topo[100010<<1], topocnt[100010<<1], sum[100010<<1], cnt[100010<<1];
DAWG g;

int main(){
    int n;
    while(scanf("%d", &n) == 1) {
        g.init();
        int totlen = 0;
        for(int i = 0; i < n; i++) {
            scanf("%s", s);
            int len = strlen(s);
            if(i > 0) g.add(10, ++totlen);
            for(int j = 0; j < len; j++) {
            g.add(s[j] - ‘0‘, ++totlen); 
        }
    }

    for(int i = 0; i <= totlen; i++) topocnt[i] = 0;
    for(int i = 0; i < g.tot; i++) topocnt[g.node[i].len]++;
    for(int i = 1; i <= totlen; i++) topocnt[i] += topocnt[i-1];
    for(int i = 0; i < g.tot; i++) topo[--topocnt[g.node[i].len]] = i;

    int ans = 0;
    for(int i = 0; i < g.tot; i++) cnt[i] = sum[i] = 0;
    cnt[0] = 1;
    for(int i = 0; i < g.tot; i++){
        int fa = topo[i];
        DAWG::Node* u = &g.node[fa];
        for(int j = 0; j < 10; j++){
            if(i == 0 && j == 0) continue;
            if(u->next[j]){
                int son = u->next[j]->id;
                cnt[son] = (cnt[son] + cnt[fa]) % 2012;
                sum[son] = (sum[son] + sum[fa]*10 + cnt[fa]*j) % 2012;
                }
            }
        ans = (ans + sum[fa]) % 2012;
        }
    printf("%d\n", ans);
    }
    return 0;
}

由于本人高二学生一枚,blog不会经常更新.

str2int

标签:状态   组成   学生   需要   amp   单个字符   nod   重复   node   

原文地址:https://www.cnblogs.com/liubinyu26/p/uva_1673_str2int.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!