【2018ACM/ICPC网络赛】焦作赛区
A Magic Mirror
题目链接:https://nanti.jisuanke.com/t/31710
题意:输入字符串,如果是“Jessy”就输出“Good Guy!",否则输出“Dare you say that again?”。Jessy的大小写不敏感。
题解:题意即题解。坑点就是大小写不敏感。
代码:
1 #include<iostream> 2 #include<string> 3 #include <algorithm> 4 5 using namespace std; 6 int main(){ 7 int T; 8 cin>>T; 9 while(T--){ 10 string s; 11 cin>>s; 12 transform(s.begin(), s.end(), s.begin(), ::toupper); 13 if(s == "JESSIE"){ 14 cout<<"Good guy!"<<endl; 15 } 16 else{ 17 cout<<"Dare you say that again?"<<endl; 18 } 19 20 } 21 return 0; 22 }
I Save the Room
题目链接:https://nanti.jisuanke.com/t/31718
题意:给你A*B*C的长宽高的立方体,让你用1*1*2的方块填满,问可不可以。
题解:猜结论。。只要有一边是偶数就行。。
代码:
1 #include <iostream> 2 using namespace std; 3 4 int a, b, c; 5 int main(){ 6 while(cin>>a>>b>>c){ 7 int ans = a * b * c; 8 if(ans & 1) 9 cout<<"No"<<endl; 10 else 11 cout<<"Yes"<<endl; 12 } 13 return 0; 14 }
G Give Candies
题目链接:https://nanti.jisuanke.com/t/31716
题意:N个糖果给N个孩子,问有多少分法。
题解:先开始和队友讨论一发以为是整数划分。。太天真了。。推了几个发现公式显而易见2^(n-1)。由于数字太大,要用到
费马小定理:
p是质数,且gcd(a,p)=1,那么 $ a^{p-1} \equiv 1 (mod p)$
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<algorithm> 5 #include<iostream> 6 #include<queue> 7 #include<map> 8 #include<stack> 9 #include<set> 10 #include<cmath> 11 using namespace std; 12 typedef long long ll; 13 const int maxn = 100015; 14 const ll mod = 1000000000+7; 15 16 ll qpow( ll a,ll n,ll mod ){ 17 ll res = 1; 18 while( n>=1 ){ 19 if( n&1 ){ 20 res = res*a%mod; 21 } 22 a = a*a%mod; 23 n >>= 1; 24 } 25 return res%mod; 26 } 27 28 ll GetNum( char str[],ll mod ){ 29 ll res = 0; 30 int len = strlen( str ); 31 for( int i=0;i<len;i++ ){ 32 res = (res*10+str[i]-'0')%mod; 33 } 34 return res; 35 } 36 37 int main(){ 38 char str[ maxn]; 39 int T; 40 cin>>T; 41 while( T--){ 42 scanf("%s",str); 43 ll n = GetNum( str,mod-1 ); 44 printf("%lld\n",qpow( 2,(n-1+mod)%mod,mod )); 45 } 46 return 0; 47 }
H String and Times
题目链接:https://nanti.jisuanke.com/t/31717
题意:给你一个字符串,让你求子串出现次数在[A,B]的有多少个。
题解:啊。板子题,SAM,SA都可以。。我直接找的板子,改了两行过的。。就当存个板子吧。
相似例题:Hust1352,Hdu6194,POJ3261.
代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <vector> 5 #include <set> 6 #include <map> 7 #include <string> 8 #include <cstring> 9 #include <stack> 10 #include <queue> 11 #include <cmath> 12 using namespace std; 13 #define rank rankk 14 #define ll long long 15 16 const int MAXN=100005; 17 int t1[MAXN],t2[MAXN],c[MAXN]; 18 19 bool cmp(int *r,int a,int b,int l){ 20 return r[a] == r[b] && r[a+l] == r[b+l]; 21 } 22 23 void da(int str[],int sa[],int rank[],int height[],int n,int m){ 24 str[n++]=0; 25 int i, j, p, *x = t1, *y = t2; 26 27 for(i = 0;i < m;i++)c[i] = 0; 28 for(i = 0;i < n;i++)c[x[i] = str[i]]++; 29 for(i = 1;i < m;i++)c[i] += c[i-1]; 30 for(i = n-1;i >= 0;i--)sa[--c[x[i]]] = i; 31 for(j = 1;j <= n; j <<= 1) 32 { 33 p = 0; 34 35 for(i = n-j; i < n; i++)y[p++] = i; 36 for(i = 0; i < n; i++)if(sa[i] >= j)y[p++] = sa[i] - j; 37 38 for(i = 0; i < m; i++)c[i] = 0; 39 for(i = 0; i < n; i++)c[x[y[i]]]++; 40 for(i = 1; i < m;i++)c[i] += c[i-1]; 41 for(i = n-1; i >= 0;i--)sa[--c[x[y[i]]]] = y[i]; 42 swap(x,y); 43 44 p = 1; x[sa[0]] = 0; 45 for(i = 1;i < n;i++) 46 x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++; 47 if(p >= n)break; 48 m = p; 49 } 50 int k = 0; n--; 51 for(i = 0;i <= n;i++)rank[sa[i]] = i; 52 for(i = 0;i < n;i++) 53 { 54 if(k)k--; 55 j = sa[rank[i]-1]; while(str[i+k] == str[j+k])k++; height[rank[i]] = k; 56 } 57 } 58 int rank[MAXN],height[MAXN]; 59 int RMQ[MAXN]; 60 int mm[MAXN]; 61 int best[20][MAXN]; 62 void initRMQ(int n) 63 { 64 mm[0]=-1; 65 for(int i=1;i<=n;i++) 66 mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1]; 67 for(int i=1;i<=n;i++)best[0][i]=i; 68 for(int i=1;i<=mm[n];i++) 69 for(int j=1;j+(1<<i)-1<=n;j++) 70 { 71 int a=best[i-1][j]; 72 int b=best[i-1][j+(1<<(i-1))]; 73 if(RMQ[a]<RMQ[b])best[i][j]=a; else best[i][j]=b; 74 } 75 } 76 int askRMQ(int a,int b) 77 { 78 int t; t=mm[b-a+1]; 79 b-=(1<<t)-1; 80 a=best[t][a];b=best[t][b]; 81 return RMQ[a]<RMQ[b]?a:b; 82 } 83 int lcp(int a,int b) 84 { 85 a=rank[a];b=rank[b]; 86 if(a>b)swap(a,b); 87 return height[askRMQ(a+1,b)]; 88 } 89 int t,k,len; 90 char sts[MAXN]; 91 int st[MAXN],sa[MAXN]; 92 multiset<int>s; 93 ll cal(int x) 94 { 95 ll an=0; 96 if(x==1) 97 { 98 an=1LL*len*(len+1LL)/2LL; 99 for(int i=1;i<=len;i++)an-=height[i]; 100 } 101 else 102 { 103 s.clear(); 104 for(int i=1;i<=x-1;i++)s.insert(height[i]); 105 for(int i=x;i<=len;i++) 106 { 107 int pre=*s.begin();s.erase(s.find(height[i-x+1]));s.insert(height[i]); 108 //printf("%d %d!\n",pre,*s.begin()); 109 an+=max(0,*s.begin()-pre); 110 } 111 } 112 return an; 113 } 114 int main(){ 115 scanf("%d",&t); 116 while(~scanf("%s",sts)){ 117 int l,r; 118 scanf("%d%d",&l,&r); 119 len=strlen(sts); 120 memset(height,0,sizeof(height)); 121 for(int i=0;i<len;i++) 122 st[i]=sts[i]-'A'+1; 123 da(st,sa,rank,height,len,27); 124 /* for(int i=1;i<=len;i++) 125 printf("%d\n",height[i]);*/ 126 printf("%lld\n",cal(l)-cal(r+1)); 127 128 } 129 return 0; 130 }
L Poor God Water
题目链接:https://nanti.jisuanke.com/t/31721
题意:三种食物的顺序不同可能会中毒。每小时从肉,鱼,巧克力吃一种。
1、如果连续三小时,只吃一样会不开心。
2、如果连续三小时,每种都吃了,而且中间吃的巧克力,就会中毒。
3、如果连续三小时,中间他吃了肉或者鱼,然后另外两个小时吃了巧克力,他也会中毒。
现在求N小时内能让他开心并且不中毒的可能的组合种数。
题解:矩阵快速幂。emmm...交了7发都没过。。。赛后群里就说BM。。QAQ我敲。。黑科技。。
暴力推出前8项以上,然后丢进去自动求。当时没补题csp就GG。呵呵哒。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <map> 8 #include <set> 9 #include <cassert> 10 using namespace std; 11 #define rep(i,a,n) for (int i=a;i<n;i++) 12 #define per(i,a,n) for (int i=n-1;i>=a;i--) 13 #define pb push_back 14 #define mp make_pair 15 #define all(x) (x).begin(),(x).end() 16 #define fi first 17 #define se second 18 #define SZ(x) ((int)(x).size()) 19 typedef vector<int> VI; 20 typedef long long ll; 21 typedef pair<int, int> PII; 22 const ll mod = 1000000007; 23 ll powmod(ll a, ll b) 24 { 25 ll res = 1; a %= mod; 26 assert(b >= 0); 27 for (; b; b >>= 1) 28 { 29 if (b & 1) 30 res = res * a%mod; 31 a = a * a%mod; 32 } 33 return res; 34 } 35 // head 36 37 int _, n; 38 namespace linear_seq 39 { 40 const int N = 10010; 41 ll res[N], base[N], _c[N], _md[N]; 42 vector<int> Md; 43 void mul(ll *a, ll *b, int k) 44 { 45 rep(i, 0, k + k) _c[i] = 0; 46 rep(i, 0, k) 47 if (a[i]) 48 rep(j, 0, k) 49 _c[i + j] = (_c[i + j] + a[i] * b[j]) % mod; 50 for (int i = k + k - 1; i >= k; i--) 51 if (_c[i]) 52 rep(j, 0, SZ(Md)) 53 _c[i - k + Md[j]] = (_c[i - k + Md[j]] - _c[i] * _md[Md[j]]) % mod; 54 rep(i, 0, k) a[i] = _c[i]; 55 } 56 int solve(ll n, VI a, VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+... 57 // printf("%d\n",SZ(b)); 58 ll ans = 0, pnt = 0; 59 int k = SZ(a); 60 assert(SZ(a) == SZ(b)); 61 rep(i, 0, k) 62 _md[k - 1 - i] = -a[i]; _md[k] = 1; 63 Md.clear(); 64 rep(i, 0, k) 65 if (_md[i] != 0) Md.push_back(i); 66 rep(i, 0, k) 67 res[i] = base[i] = 0; 68 res[0] = 1; 69 while ((1ll << pnt) <= n) pnt++; 70 for (int p = pnt; p >= 0; p--) 71 { 72 mul(res, res, k); 73 if ((n >> p) & 1) 74 { 75 for (int i = k - 1; i >= 0; i--) res[i + 1] = res[i]; res[0] = 0; 76 rep(j, 0, SZ(Md)) res[Md[j]] = (res[Md[j]] - res[k] * _md[Md[j]]) % mod; 77 } 78 } 79 rep(i, 0, k) ans = (ans + res[i] * b[i]) % mod; 80 if (ans < 0) ans += mod; 81 return ans; 82 } 83 VI BM(VI s) 84 { 85 VI C(1, 1), B(1, 1); 86 int L = 0, m = 1, b = 1; 87 rep(n, 0, SZ(s)) 88 { 89 ll d = 0; 90 rep(i, 0, L + 1) d = (d + (ll)C[i] * s[n - i]) % mod; 91 if (d == 0) ++m; 92 else if (2 * L <= n) 93 { 94 VI T = C; 95 ll c = mod - d * powmod(b, mod - 2) % mod; 96 while (SZ(C) < SZ(B) + m) C.pb(0); 97 rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod; 98 L = n + 1 - L; B = T; b = d; m = 1; 99 } 100 else 101 { 102 ll c = mod - d * powmod(b, mod - 2) % mod; 103 while (SZ(C) < SZ(B) + m) C.pb(0); 104 rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod; 105 ++m; 106 } 107 } 108 return C; 109 } 110 int gao(VI a, ll n) 111 { 112 VI c = BM(a); 113 c.erase(c.begin()); 114 rep(i, 0, SZ(c)) c[i] = (mod - c[i]) % mod; 115 return solve(n, c, VI(a.begin(), a.begin() + SZ(c))); 116 } 117 }; 118 119 int main() 120 { 121 int t; 122 scanf("%d",&t); 123 while (t--) 124 { 125 long long n; 126 scanf("%lld",&n); 127 vector<int>v({3,9,20,46,106,244,560,1286,2956,6794}); 128 //VI{1,2,4,7,13,24} 129 printf("%lld\n", linear_seq::gao(v, n - 1)); 130 } 131 }