首页 > 其他分享 >HDU 4436 str2int

HDU 4436 str2int

时间:2022-11-09 19:00:23浏览次数:35  
标签:HDU int sum ++ next fa 4436 ins str2int


Problem Description


In this problem, you are given several strings that contain only digits from '0' to '9', inclusive.
An example is shown below.
101
123
The set S of strings is consists of the N strings given in the input file, and all the possible substrings of each one of them.
It's boring to manipulate strings, so you decide to convert strings in S into integers.
You can convert a string that contains only digits into a decimal integer, for example, you can convert "101" into 101, "01" into 1, et al.
If an integer occurs multiple times, you only keep one of them. 
For example, in the example shown above, all the integers are 1, 10, 101, 2, 3, 12, 23, 123.
Your task is to calculate the remainder of the sum of all the integers you get divided by 2012.


 



Input


There are no more than 20 test cases.
The test case starts by a line contains an positive integer N.
Next N lines each contains a string consists of one or more digits.
It's guaranteed that 1≤N≤10000 and the sum of the length of all the strings ≤100000.
The input is terminated by EOF.


 



Output


An integer between 0 and 2011, inclusive, for each test case.


 



Sample Input


5 101 123 09 000 1234567890


 



Sample Output


202


 



后缀自动机+拓扑排序


#include<cstdio>    
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 100005;

class SAM
{
const static int maxn = 400005; //节点个数
const static int size = 11; //字符的范围
const static char base = '0'; //字符的基准

class node
{
public:
node *fa, *next[size];
int len, sum, cnt, ins;
node* clear(int x)
{
fa = 0; len = x;
ins = sum = cnt = 0;
memset(next, 0, sizeof(next));
return this;
}
}nd[maxn]; //节点的设置

node *root, *last; //根节点,上一个节点
int tot; //总节点数
public:
void clear()
{
last = root = &nd[tot = 0];
nd[0].clear(0);
} //初始化
void insert(char ch)
{
node *p = last, *np = nd[++tot].clear(p->len + 1);
last = np;
int x = ch - base;
while (p&&p->next[x] == 0) p->next[x] = np, np->ins++, p = p->fa;
if (p == 0) { np->fa = root; return; }

node* q = p->next[x];
if (p->len + 1 == q->len) { np->fa = q; return; }

node *nq = nd[++tot].clear(p->len + 1);
for (int i = 0; i < size; i++)
if (q->next[i]) nq->next[i] = q->next[i], q->next[i]->ins++;
nq->fa = q->fa;
q->fa = np->fa = nq;
while (p &&p->next[x] == q) p->next[x] = nq, nq->ins++, q->ins--, p = p->fa;
} //插入操作
void query()
{
int ans = 0, base = 2012;
root->cnt = 1;
root->sum = 0;
queue<node*> p;
p.push(root);
while (!p.empty())
{
node*q = p.front(); p.pop();
(ans += q->sum) %= base;
for (int i = 0; i < size; i++)
if (q->next[i])
{
q->next[i]->ins--;
if (q->next[i]->ins == 0) p.push(q->next[i]);
if ((q == root&&i == 0) || i == 10) continue;
(q->next[i]->cnt += q->cnt) %= base;
(q->next[i]->sum += q->sum * 10 + q->cnt*i) %= base;
}
}
printf("%d\n", ans);
}
}sam;

int n;
char s[maxn];

int main()
{
while (~scanf("%d", &n))
{
sam.clear();
while (n--)
{
scanf("%s", s);
for (int i = 0; s[i]; i++) sam.insert(s[i]);
if (n) sam.insert('9' + 1);
}
sam.query();
}
return 0;
}


标签:HDU,int,sum,++,next,fa,4436,ins,str2int
From: https://blog.51cto.com/u_15870896/5838306

相关文章

  • HDU 5264 pog loves szh I
    ProblemDescriptionPoghaslotsofstrings.Andhealwaysmixestwoequal-lengthstrings.Forexample,therearetwostrings:"abcd"and"efgh".Afterm......
  • HDU 5639 Deletion
    ProblemDescriptionG with n verticesand m edges.Everytime,youcanselectseveraledgesanddeletethem.Theedgesselectedmustmeetthe......
  • HDU 5637 Transform
    ProblemDescriptionn integersaregiven.Foraninteger x youcandothefollowingoperations:+letthebinaryrepresentationof x be ......
  • HDU 1403 Longest Common Substring
    ProblemDescriptionGiventwostrings,youhavetotellthelengthoftheLongestCommonSubstringofthem.Forexample:str1=bananastr2=ciana......
  • HDU 4658 Integer Partition
    ProblemDescriptionGivenn,k,calculatethenumberofdifferent(unordered)partitionsofnsuchthatnopartisrepeatedkormoretimes.  ......
  • HDU 5638 Toposort
    ProblemDescriptionn verticesand m edges.Youareallowedtodeleteexact k InputT indicatingthenumberoftestcases.Fore......
  • HDU 4651 Partition
    ProblemDescriptionHowmanywayscanthenumbers1to15beaddedtogethertomake15?Thetechnicaltermforwhatyouareaskingisthe"numberofpart......
  • HDU 1028
    如果只有\(1\)数字,多项式为:\(1+x+x^2+x^3+\ldots\)。如果只有\(2\)数字,多项式为:\(1+x^2+x^4+x^6+\ldots\)。……如果只有\(k\)数字,多项式为:\(1+x^k+x^{2k}+x^{3......
  • B - K-th Number HDU - 6231 (二分 尺取)
    WindowsSource2017中国大学生程序设计竞赛-哈尔滨站题意给一个数组,在所有长度大于等于k的区间内,找出第\(k\)大的数,放到另一个数组中,然后在新数组中找到第M大的数。思......
  • HDU-1260 Tickets
    感觉题目还是比较水的,我这个蒟蒻也能写出来hh。思路:f[i]是前i个人(包含第i个)买票需要花费的总时间,第i个人买票所需时间,可以自己单买(f[i-1]+a[i]),也可以和前面那个人拼......