今天H题真的有毒,居然不放单组数据范围……SAM卡了半天空间打死过不去
J题卡牛顿迭代常数也是很那啥的
补题进度:6/12
A.
签到题,模拟
1 #include<bits/stdc++.h> 2 using namespace std; 3 int T; 4 int main() 5 { 6 scanf("%d",&T); 7 while(T--) 8 { 9 string s; 10 cin>>s; 11 for(int i=0;i<s.length();++i) 12 { 13 if('A'<=s[i]&&s[i]<='Z')s[i]=s[i]-'A'+'a'; 14 } 15 if(s=="jessie")puts("Good guy!"); 16 else puts("Dare you say that again?"); 17 } 18 return 0; 19 }
G.
打表找规律,发现是2^(n-1),欧拉定理指数取模一下
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 1000005 4 using namespace std; 5 const ll mod=1000000007; 6 int T; 7 char s[maxn]; 8 ll fastpow(ll a,ll p) 9 { 10 ll ans=1; 11 while(p) 12 { 13 if(p&1)ans=ans*a%mod; 14 a=a*a%mod; 15 p>>=1; 16 } 17 return ans; 18 } 19 int main() 20 { 21 scanf("%d",&T); 22 while(T--) 23 { 24 scanf("%s",s+1); 25 ll n=0,len=strlen(s+1); 26 for(int i=1;i<=len;++i)n=n*10+s[i]-'0',n%=(mod-1); 27 n=(n-1+(mod-1))%(mod-1); 28 ll ans=fastpow(2,n); 29 cout<<ans<<endl; 30 } 31 return 0; 32 }
H.
后缀自动机裸题,统计right集合大小在[A,B]之间的,每次maxlen[u]-minlen[u]+1就行
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 200005 4 using namespace std; 5 int ch[maxn][26]; 6 int fa[maxn],cnt,last,rt; 7 ll sz[maxn],dis[maxn]; 8 void init() 9 { 10 cnt=0; 11 rt=last=++cnt; 12 memset(fa,0,sizeof(fa)); 13 memset(dis,0,sizeof(dis)); 14 memset(sz,0,sizeof(sz)); 15 memset(ch,0,sizeof(ch)); 16 } 17 inline int newnode(int x){dis[++cnt]=x;return cnt;} 18 void add(int x) 19 { 20 int np=newnode(dis[last]+1),p=last; 21 for(;p&&(!ch[p][x]);p=fa[p])ch[p][x]=np; 22 if(!p)fa[np]=rt; 23 else 24 { 25 int q=ch[p][x]; 26 if(dis[q]==dis[p]+1)fa[np]=q; 27 else 28 { 29 int nq=newnode(dis[p]+1); 30 memcpy(ch[nq],ch[q],sizeof(ch[q])); 31 fa[nq]=fa[q]; 32 fa[q]=fa[np]=nq; 33 for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq; 34 } 35 } 36 last=np; 37 sz[np]=1; 38 } 39 char s[maxn]; 40 int A,B; 41 int c[maxn],t[maxn]; 42 ll count() 43 { 44 memset(c,0,sizeof(c)); 45 memset(t,0,sizeof(t)); 46 ll ans=0; 47 for(int i=1;i<=cnt;i++)c[dis[i]]++; 48 for(int i=1;i<=cnt;i++)c[i]+=c[i-1]; 49 for(int i=cnt;i;i--)t[c[dis[i]]--]=i; 50 for(int i=cnt;i;i--){int x=t[i];sz[fa[x]]+=sz[x];} 51 for(int i=2;i<=cnt;++i)if(A<=sz[i]&&sz[i]<=B)ans+=dis[i]-dis[fa[i]]; 52 return ans; 53 } 54 int main() 55 { 56 while(~scanf("%s%d%d",s+1,&A,&B)) 57 { 58 init(); 59 for(int i=1;s[i];++i)add(s[i]-'A'); 60 cout<<count()<<endl; 61 } 62 return 0; 63 }
I.
观察一下,三个都是奇数显然不行,否则显然可以
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a,b,c; 4 int main() 5 { 6 while(~scanf("%d%d%d",&a,&b,&c)) 7 { 8 if((a&1)&&(b&1)&&(c&1))puts("No"); 9 else puts("Yes"); 10 } 11 return 0; 12 }
K.
多重背包计数,暴力dp为O(N*S*S)的
考虑把转移中的O(S)优化掉:
如果没有c[i]限制,那么每次记录 mod v[i]意义下分类的总和,每次加上总和即可
现在有了c[i]限制,考虑mod v[i]意义下是连续的一段转移过来的,所以用滑动窗口维护下就行了
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 22 4 #define maxc 10005 5 using namespace std; 6 const ll mod=1000000007; 7 int T,n,q; 8 ll v[maxn],c[maxn]; 9 ll dp[maxn][maxc],tmp[maxn]; 10 queue<ll> que[maxn]; 11 int main() 12 { 13 scanf("%d",&T); 14 while(T--) 15 { 16 memset(dp,0,sizeof(dp)); 17 scanf("%d%d",&n,&q); 18 for(int i=1;i<=n;++i)scanf("%lld%lld",&v[i],&c[i]); 19 dp[0][0]=1; 20 for(int i=1;i<=n;++i) 21 { 22 memset(tmp,0,sizeof(tmp)); 23 for(int i=0;i<=20;++i)while(!que[i].empty())que[i].pop(); 24 for(int j=0;j<=10000;++j) 25 { 26 tmp[j%v[i]]+=dp[i-1][j]; 27 tmp[j%v[i]]%=mod; 28 if(j>=((1<<c[i]))*v[i])tmp[j%v[i]]-=que[j%v[i]].front(),que[j%v[i]].pop(),tmp[j%v[i]]=(tmp[j%v[i]]%mod+mod)%mod; 29 que[j%v[i]].push(dp[i-1][j]); 30 dp[i][j]+=tmp[j%v[i]];dp[i][j]%=mod; 31 } 32 } 33 while(q--) 34 { 35 int s; 36 scanf("%d",&s); 37 printf("%d\n",(int)dp[n][s]); 38 } 39 } 40 return 0; 41 }
L.
dp;
f(i,j,k)表示现在是第i天,状态为j(0/1/2),上一天状态为k(0/1/2)
f(i,0,0)=f(i-1,0,1)+f(i-1,0,2);
f(i,0,1)=f(i-1,1,0)+f(i-1,1,1)+f(i-1,1,2);
f(i,0,2)=f(i-1,2,0)+f(i-1,2,2);
f(i,1,0)=f(i,0,1);
f(i,1,1)=f(i,0,0);
f(i,1,2)=f(i,0,2);
f(i,2,0)=f(i-1,0,0)+f(i-1,0,1);
f(i,2,1)=f(i,2,0);
f(i,2,2)=f(i-1,2,0)+f(i-1,2,1);
然后发现都是线性齐次递推,直接构造9*9的矩阵,上矩阵快速幂
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const ll mod=1000000007; 5 int T; 6 ll n; 7 const int m=9; 8 struct Matrix 9 { 10 ll a[25][25]; 11 void clear(){memset(a,0,sizeof(a));} 12 void init(){memset(a,0,sizeof(a));for(int i=1;i<=m;i++)a[i][i]=1;} 13 }; 14 Matrix operator * (Matrix a,Matrix b) 15 { 16 Matrix c;c.clear(); 17 for(int i=1;i<=m;i++) 18 for(int j=1;j<=m;j++) 19 for(int k=1;k<=m;k++) 20 c.a[i][j]+=a.a[i][k]*b.a[k][j]%mod,c.a[i][j]%=mod; 21 return c; 22 } 23 Matrix fastpow(Matrix a,ll p) 24 { 25 Matrix ans;ans.init(); 26 for(;p;p>>=1,a=a*a)if(p&1)ans=ans*a; 27 return ans; 28 } 29 int main() 30 { 31 cin>>T; 32 while(T--) 33 { 34 cin>>n; 35 if(n==1) 36 { 37 puts("3"); 38 continue; 39 } 40 Matrix A;A.clear(); 41 A.a[1][2]=A.a[1][3]=A.a[2][4]=A.a[2][5]=A.a[2][6]=A.a[3][7]=A.a[3][9]=A.a[4][4]=A.a[4][5]=A.a[4][6]=1; 42 A.a[5][2]=A.a[5][3]=A.a[6][7]=A.a[6][9]=A.a[7][1]=A.a[7][2]=A.a[8][1]=A.a[8][2]=A.a[9][7]=A.a[9][8]=1; 43 Matrix res=fastpow(A,n-2); 44 Matrix tmp;tmp.clear(); 45 for(int i=1;i<=9;++i)tmp.a[i][1]=1; 46 Matrix R=res*tmp; 47 ll ans=0; 48 for(int i=1;i<=9;++i)ans+=R.a[i][1]; 49 ans%=mod; 50 cout<<ans<<endl; 51 } 52 return 0; 53 }