zoukankan      html  css  js  c++  java
  • #高精度,模拟,vector#C 前缀

    From 2020牛客NOIP赛前集训营-提高组(第二场)

    传送门


    分析

    像我这么菜就只会模拟呀(考场CE全部爆零QWQ)
    题意就是不断跳到下一个字母问总共跳的长度有多长,
    首先用一个变量存下初始位置(len-1),(以下使用0开头,方便后面统计)
    但显然暴力跳会T飞,必然存在循环节,长度为字母个数所贡献的答案为字符串长度
    那么考虑高精度,求出有多少个循环节贡献的字符串长度,这里可以将星号视为所有字母,
    关键就是余数部分,考虑用vector存下每个字母的位置,以及该位置下对应vector的位置,
    那直接vector下标往后移余数位就可以了呀。


    代码

    #include <cstdio>
    #include <cstring>
    #include <cctype>
    #include <vector>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int mod=998244353,N=100011;
    char S[N],T[N]; vector<int>K[27];
    int Test,loc[N][2],c[N],len,LEN,ans;
    inline void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
    inline signed doit(int l,int r,int C1,int C2){
    	rr int g=0,s=0,tot=0,cho;
    	for (rr int i=l;i<=r;++i) c[i-l+1]=T[i]^48;
    	for (cho=r-l+1;!c[cho];--cho); --c[cho];
    	for (rr int i=cho+1;i<=r-l+1;++i) c[i]=9;
    	for (rr int i=l;i<=r;++i,g=s%C1)
    		s=g*10+c[i-l+1],c[++tot]=s/C1;
    	s=0;
    	for (rr int i=tot;i;--i)
    		s+=c[i]*C2,c[i]=s%10,s/=10;
    	for (rr int i=1;i<=tot;++i) s=(s*10ll+c[i])%mod;
    	Mo(ans,s);
    	return g;
    }
    signed main(){
    	scanf("%s%d",S,&Test),len=strlen(S);
    	for (rr int i=0;i<len;++i) K[S[i]^96].push_back(i),loc[i][0]=K[S[i]^96].size()-1;
    	for (rr int i=0;i<len;++i) K[0].push_back(i),loc[i][1]=i;
    	for (rr int LEN;Test;--Test){
    		scanf("%s",T),LEN=strlen(T),ans=0;
    		rr int l=0,r=0,beg=len-1,flag=1;
    		for (rr int f=0,now;l<LEN;l=++r){
    			if (T[l]=='*') T[l]=96,f=1; else f=0;
    			rr int G=T[l]^96,siz=K[G].size(),nxt;
    			if (!siz) {flag=0; break;}
    			if (l+1<LEN&&isdigit(T[l+1]))
    			    for (;r+1<LEN&&isdigit(T[r+1]);++r);
    			if (K[G][siz-1]<=beg) nxt=K[G][0];
    			    else nxt=*upper_bound(K[G].begin(),K[G].end(),beg);
    			if (beg<nxt) Mo(ans,nxt-beg),beg=nxt;
    			    else Mo(ans,len-beg+nxt),beg=nxt;
    			if (l<r){
    				if (now=doit(l+1,r,siz,len)){
    					nxt=K[G][(loc[beg][f]+now)%siz];
    					if (beg<nxt) Mo(ans,nxt-beg),beg=nxt;
    					    else Mo(ans,len-beg+nxt),beg=nxt;
    				}
    			}
    		}
    		if (!flag) printf("-1
    ");
    		    else printf("%d
    ",ans);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    Eclipse添加Junit测试
    Java基础—JDK环境变量配置
    Java基础—常用类之String类
    Spring3+ibatis (SQL Server)+pager-taglib.tld查询分页的实现
    【solr专题之中的一个】Solr高速入门
    【翻译自mos文章】在12c中Create or Truncate Table时非常慢,等待事件为 DFS Lock Handle wait
    Ubuntu x86 64 settup nginx rtmp server
    [POJ 1390]Blocks
    Spring中AOP的使用
    Cocos2dx 小技巧(十三)聊聊坐标系
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13850131.html
Copyright © 2011-2022 走看看