CF 题目集锦 PART 6 # 265 div 1 C

【原题】

C. Substitutes in Number
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Andrew and Eugene are playing a game. Initially, Andrew has string s, consisting of digits. Eugene sends Andrew multiple queries of type "di → ti", that means "replace all digits di in string s with substrings equal to ti". For example, if s = 123123, then query "2 → 00" transforms s to10031003, and query "3 → " ("replace 3 by an empty string") transforms it to s = 1212. After all the queries Eugene asks Andrew to find the remainder after division of number with decimal representation equal to s by 1000000007 (109 + 7). When you represent s as a decimal number, please ignore the leading zeroes; also if s is an empty string, then it's assumed that the number equals to zero.

Andrew got tired of processing Eugene's requests manually and he asked you to write a program for that. Help him!

Input

The first line contains string s (1 ≤ |s| ≤ 105), consisting of digits — the string before processing all the requests.

The second line contains a single integer n (0 ≤ n ≤ 105) — the number of queries.

The next n lines contain the descriptions of the queries. The i-th query is described by string "di->ti", where di is exactly one digit (from 0 to 9), tiis a string consisting of digits (ti can be an empty string). The sum of lengths of ti for all queries doesn't exceed 105. The queries are written in the order in which they need to be performed.

Output

Print a single integer — remainder of division of the resulting number by 1000000007 (109 + 7).

Sample test(s)
input
123123
1
2->00
output
10031003
input
123123
1
3->
output
1212
input
222
2
2->0
0->7
output
777
input
1000000008
0
output
1
Note

Note that the leading zeroes are not removed from string s after the replacement (you can see it in the third sample).


【题意】给定初始串N和M个操作:x->y。每次把N中的所有x替换成y。(y可以为空或多个字符,但x=1)。求最终串取模1000000007的余数。

【分析】开始发现len(y)是规定的,于是想使。直接暴力开vector,倒着修改每一个变换。

【代码1】

#include<cstdio>
#include<vector>
#include<cstring>
#define N 200005
#define P 1000000007
#define CH getchar()
#define pb push_back
using namespace std;
vector<int>C[N];
int b[N],num[N],first[N],last[N],re[N],q[N],pow[N],find[10];
int Q,i,n,m,node,ans;char ch,a[N];
inline void get_back()
{
  for (int i=Q;i;i--)
  {
    /*if (!find[num[i]]) 
    {
      find[num[i]]=1;
      for (int j=first[i]+1;j<=last[i];j++)
        C[num[i]].pb(re[j]);
      continue;
    }*/
    int h=0;
    for (int j=first[i]+1;j<=last[i];j++)
      if (find[re[j]])
      {
        for (int k=0;k<C[re[j]].size();k++)
          q[++h]=C[re[j]][k];
      }
      else q[++h]=re[j];
    C[num[i]].clear();find[num[i]]=1;
    for (int j=1;j<=h;j++) C[num[i]].pb(q[j]);
  }
}
inline void find_back()
{
  int k;
  for (int i=1;i<=n;i++)
    if (find[k=(a[i]-'0')])
    {
      for (int j=0;j<C[k].size();j++)
        b[++m]=C[k][j];
    }
    else b[++m]=k;
}
int main()
{
  pow[1]=1;for (i=2;i<=200000;i++) pow[i]=pow[i-1]*10ll%P;
  scanf("%s",a+1);n=strlen(a+1);
  scanf("%d",&Q);
  for (i=1;i<=Q;i++)
  {
    ch=CH;for (;ch<'0'||ch>'9';ch=CH);
    num[i]=ch-'0';first[i]=last[i]=++node;
    for (ch=CH;ch!='\n'&&ch!='\r';ch=CH) 
      if (ch>='0'&&ch<='9') re[++last[i]]=ch-'0';
    node=last[i];
  }
  get_back();
  find_back();
  for (i=1;i<=m;i++) (ans+=pow[m-i+1]*1ll*b[i]%P)%=P;
  printf("%d",ans);
  return 0;
}

【分析】结果被卡RE了。后来想想也是必然。毕竟还开了vector......于是就瞬间不会做了=

看了题解,其实思路都是差不多的,但是它并不是暴力修改某个字符对应的规则,而是直接把这个规则的值(取模后)记下来。还是很好懂的,但是觉得正式赛可能想不出来吧= =。

【AC代码】

#include<cstdio>
#include<cstring>
#define N 200005
#define P 1000000007
#define CH getchar()
using namespace std;
int num[N],first[N],last[N],re[N],pow[N],s[N];
int Q,i,n,m,node,ans;char ch,a[N];
inline void get_back()
{
  for (int i=0;i<=9;i++) pow[i]=10,s[i]=i;
  for (int i=Q;i;i--)
  {
    if (last[i]==first[i]) s[num[i]]=0,pow[num[i]]=1;
    int Pow=1,S=0;
    for (int j=first[i]+1;j<=last[i];j++)
      S=S*1ll*pow[re[j]]%P,(S+=s[re[j]])%=P,
      Pow=Pow*1ll*pow[re[j]]%P;
    pow[num[i]]=Pow;s[num[i]]=S;
  }
}
int main()
{
  scanf("%s",a+1);n=strlen(a+1);
  scanf("%d",&Q);
  for (i=1;i<=Q;i++)
  {
    ch=CH;for (;ch<'0'||ch>'9';ch=CH);
    num[i]=ch-'0';first[i]=last[i]=++node;
    for (ch=CH;ch!='\n'&&ch!='\r';ch=CH) 
      if (ch>='0'&&ch<='9') re[++last[i]]=ch-'0';
    node=last[i];
  }
  get_back();
  for (i=1;i<=n;i++) ans=ans*1ll*pow[a[i]-'0']%P,(ans+=s[a[i]-'0'])%=P;
  printf("%d",ans);
  return 0;
}

你可能感兴趣的:(题解,模拟,CF,刷题记录)