A. Clam and Fish \looparrowright

题目描述

There is a fishing game as following.
The game contains nn stages, numbered from 11 to nn.
There are four types of stages (numbered from 00 to 33). Type 00: There are no fish and no clam in this stage. Type 11: There are no fish and one clam in this stage. Type 22: There are one fish and no clam in this stage. Type 33: There are one fish and one clam in this stage.
In each stage, you can do exactly one of the following four actions.
If there is a clam in the stage, you can use this clam to make one pack of fish bait. And the number of packs of fish bait you have is increased by one. You can use this pack of fish bait to catch fish after this stage.
If there is one fish in the stage, you can catch this fish without any fish bait. After this stage, the number of packs of fish bait you have is not changed.
If you have at least one pack of fish bait. You can always catch one fish by using exactly one pack of fish bait even if there are no fish in this stage. After this stage, the number of packs of fish bait you have is decreased by one.
You can do nothing.
Now, you are given nn and the type of each stage. Please calculate the largest number of fish you can get in the fishing game.

输入描述

The first line contains one integer tt (1t2.5×1051 \leqslant t \leqslant 2.5 \times 10^5), indicating the number of test cases.
There are two lines in each test. The first line contains one integer nn (1n2×1061 \leqslant n \leqslant 2 \times 10^6), indicating the number of stages in this game. The second line contains a string with length nn. The ii-th character of this string indicates the type of the ii-th stage.
The sum of nn across the test cases doesn’t exceed 2×1062 \times 10^6.

输出描述

For each test case print exactly one integer indicating the maximum number of fish you can catch in the game configuration.

示例1

输入

1
2
3
4
5
2  
4
0103
1
1

输出

1
2
2  
0

备注

One possible scenario you can catch two fishes is as follow.
stage 11: Do nothing.
stage 22: Make a pack of fish bait.
stage 33: Catch a fish by a pack of fish bait.
stage 44: Catch the fish that appears in the stage.

分析

首先明确,要是当前的状态有鱼,那么直接抓鱼。若当前为状态 22,那么用鱼饵钓鱼显然不如直接抓鱼实惠;若当前状态为 33,虽然可以获得鱼饵,但是获得鱼饵也是为了在将来花费这个鱼饵钓到鱼,问题是将来可能不会再有钓鱼的机会(鱼饵多余,已经是最后一天……),不如放弃这个鱼饵,直接抓鱼。
若当前状态没有鱼,那么鱼饵要尽量在没有蛤蜊的时候用掉,有蛤蜊的状态用来获取鱼饵。若当前状态为 00,什么都没有;那么有鱼饵的话直接用来抓鱼,否则就什么都不做。若当前状态为 11,如果没有鱼饵,那就不必思考,直接获取鱼饵;如果有鱼饵,再来考虑要不要钓鱼;因为鱼饵是为将来状态为 00 的时候准备的,如果钓鱼后,拥有的鱼饵足够将来状态为 00 的那几天使用,就可以放心地钓鱼,否则就将蛤蜊做成鱼饵。
值得一提的是,需要逆向预处理第 ii 天后状态为 00 的天数,再正向进行贪心。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: 2020牛客暑期多校训练营(第三场) Problem A
Date: 8/14/2020
Description: Greedy
*******************************************************************/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2000005;
int _;
char days[N];
int n;
int leftover[N];
int bait,fish;
inline void init();
int main(){
for(cin>>_;_;_--){
scanf("%d%s",&n,days+1);
init();
int i;
for(i=n;i>=1;i--){
leftover[i]+=days[i]=='0';
leftover[i]+=leftover[i+1];
}
for(i=1;i<=n;i++){
if(days[i]=='0'){
//没鱼 没蛤蜊
if(bait){
//有鱼饵 可以抓鱼
bait--;
fish++;
}
}else if(days[i]=='1'){
//没鱼 有蛤蜊
if(!bait){
//没鱼饵 只能将蛤蜊做成鱼饵
bait++;
}else{
//有鱼饵 考虑要不要抓鱼
if(leftover[i]<bait){
//当前鱼饵足够在后面没鱼没蛤蜊的情况下抓鱼
//现在可以抓鱼
fish++;
bait--;
}else{
//做成鱼饵 在将来没鱼没蛤蜊的情况下抓鱼
bait++;
}
}
}else{
//有鱼直接抓 不能错失机会
fish++;
}
}
printf("%d\n",fish);
}
return 0;
}
inline void init(){
bait=fish=0;
fill(leftover,leftover+n+2,0);
}

B. Classical String Problem \looparrowright

题目描述

Given a string SS consists of lower case letters. You’re going to perform QQ operations one by one. Each operation can be one of the following two types.
Modify: Given an integer xx, you need to modify SS according to the value of xx. If xx is positive, move the leftmost xx letters in SS to the right side of SS; otherwise, move the rightmost x|x| letters in SS to the left side of SS.
Answer: Given a positive integer xx. Please answer what the xx-th letter in the current string SS is.

输入描述

There are Q+2Q+2 lines in the input. The first line of the input contains the string SS. The second line contains the integer QQ. The following QQ lines each denotes an operation. You need to follow the order in the input when performing those operations.
Each operation in the input is represented by a character cc and an integer xx. If c=='M', this operation is a modify operation, that is, to rearrange SS according to the value of xx; if c=='A', this operation is an answer operation, to answer what the xx-th letter in the current string SS is.
2S2×1062 \leqslant |S| \leqslant 2 \times 10^6 (S|S| stands for the length of the string SS).
SS consists of lower case letters.
1Q8×1051 \leqslant Q \leqslant 8 \times 10^5.
c=Mc = 'M' or A'A'. If c=Mc = 'M', 1x<S1 \leqslant |x| < |S|. If c=Ac = 'A', 1xS1 \leqslant x \leqslant |S|.
There is at least one operation in the input satisfies c=Ac = 'A'.

输出描述

For each answer operation, please output a letter in a separate line representing the answer to the operation. The order of the output should match the order of the operations in the input.

示例1

输入

1
2
3
4
5
6
7
8
nowcoder
6
A 1
M 4
A 6
M -3
M 1
A 1

输出

1
2
3
n
o
w

备注

Initially, SS is “nowcoder”, six operations follow.
The 11-st operation is asking what the 11-st letter is. The answer is ‘n’.
The 22-nd operation is to move the leftmost 44 letters to the rightmost side, so SS is modified to “odernowc”.
The 33-rd operation is asking what the 66-th letter is. The answer is ‘o’.
The 44-th operation is to move the rightmost 33 letters to the leftmost side, so SS is modified to “owcodern”.
The 55-th operation is to move the leftmost 11 letter to the rightmost side, so SS is modified to “wcoderno”.
The 66-th operation is asking what the 11-st letter is. The answer is ‘w’.

分析

将字符串看作一个环,定义一个指针 pointerpointer 指向字符串的起点,从起点开始逆时针遍历整个环,得到的就是当前字符串;不论如何更改,环的结构是不会变的。查询时,从起点开始,逆时针经过 xx 个点,最终到达的点即为询问的答案;更新时,若 x<0x<0,要将字符串末尾的某个字符作为起点,将指针顺时针移动 x-x 次;否则,将指针逆时针移动 xx 次。环上的移动,通过对字符串长度 lenlen 取模来体现。
2020牛客多校第三场.png

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: 2020牛客暑期多校训练营(第三场) Problem B
Date: 8/14/2020
Description: Pointer Simulation
*******************************************************************/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=2000005;
int _;
char s[N];
int q;
int len;
int main(){
scanf("%s%d",s,&q);
len=strlen(s);
int pointer=0;
while(q--){
char c;
int x;
getchar();
scanf("%c%d",&c,&x);
if(c=='M'){
//取模体现环上移动的性质
pointer=(pointer+x+len)%len;
}else{
printf("%c\n",s[(pointer+x-1)%len]);
}
}
return 0;
}

F. Fraction Construction Problem \looparrowright

题目描述

There are tt queries.
In each query, you are given two positive integers aa and bb (a,b2×106)(a, b \leqslant 2 \times 10^6).
Please print a line consists of four positive integers c,d,e,f satisfying the following constraints: cdef=ab\frac{c}{d} - \frac{e}{f} = \frac{a}{b}, d<bd < b and f<bf < b, 1c,e4×10121 \leqslant c,e \leqslant 4 \times 10^{12}.
If there are multiple solutions, you can print anyone.
If there are no solution, please print -1 -1 -1 -1 in this line.

输入描述

The first line contains one integer tt (1t105)(1 \leqslant t \leqslant 10^5), the number of test cases.
The only line of each test case contains two integers aa and bb (1a,b2×106)(1 \leqslant a, b \leqslant 2 \times 10^6).

输出描述

For each test case print four integers c,d,e,fc,d,e,f. If there are no solution, c,d,e,fc,d,e,f should all be 1-1.

示例1

输入

1
2
3
4
3
4 1
1 6
37 111

输出

1
2
3
-1 -1 -1 -1
1 2 1 3
145 87 104 78

分析

gcd(a,b)>1\gcd(a,b)>1,代表分数 ab\frac{a}{b} 可以约分为 a/gcd(a,b)b/gcd(a,b)\frac {a/\gcd(a,b)}{b/\gcd(a,b)}。简便起见,直接令 d=f=bgcd(a,b)d=f=\frac{b}{\gcd(a,b)},那么就有 ce=agcd(a,b)c-e=\frac{a}{\gcd(a,b)},有一组解为 c=agcd(a,b)c=\frac{a}{\gcd(a,b)}e=1e=1
aba\bot b,那么ab\frac{a}{b} 已经是最简分式,将等式左边通分后,可得 fcdedf=ab\frac{fc-de}{df}=\frac{a}{b}。首先,当 bb 为质数的幂时,无解(文末给出证明)。接下来考虑 bb 有多个不相同质因子的情况。根据算数基本定理,可以将 bb 写成有限个质数的乘积,b=p1k1p2k2pmkmb=p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m}。方便起见,直接令 df=bdf=bfcde=afc-de=afcde=afc-de=a 是一个裴蜀方程,当且仅当 gcd(f,d)a\gcd(f,d)\mid a 时方程有整数解。若能构造得到的 f,df,d 使得 gcd(f,d)=1\gcd(f,d)=1,那么方程一定有整数解。显然这样的构造方案是存在的,令 d=p1k1d=p_1^{k_1}f=p2k2pmkm=bp1k1f=p_2^{k_2}\cdots p_m^{k_m}=\frac{b}{p_1^{k_1}},就有 gcd(d,f)=1\gcd(d,f)=1。可以用扩展欧几里得算法求出 c,ec,e 的特解 c0,e0c_0,e_0 ,为了满足条件 1c,e4×10121\leqslant c,e\leqslant 4\times 10^{12},不妨让 c,ec,e 尽量向 4×10124\times 10^{12} 靠近。令 top=4×1012top=4\times 10^{12},求一个不等式组即可得到 c,ec,e 的上界。有不等式组 $\begin{cases}c_0+kd\leqslant top\\e_0+kf\leqslant top\end{cases}$,解得 kmin(topc0d,tope0f)k\leqslant \min\left(\left\lfloor\frac{top-c_0}{d}\right\rfloor,\left\lfloor\frac{top-e_0}{f}\right\rfloor\right)
接下来给出证明:当 aba\bot bbb 为质数的幂次时,无解。
df=kbdf=kbfcde=kafc-de=kab=ptb=p^t。由于 bb 是质数的幂次,可设 d=k1pxd=k_1p^xf=k2pyf=k_2p^y,其中 k1k2=kk_1k_2=kx+y=tx+y=t。那么有 k2pyck1pxdkpt=ab()\frac{k_2p^yc-k_1p^xd}{kp^t}=\frac{a}{b}(\ast)kpt=bkp^t=b。很显然,()(\ast) 式的左边分式可以上下同除以 lcm(px,py)\mathrm{lcm}(p^x,p^y) 进行约分;又 kpt=bkp^t=b,故 k2pyck1pxd=ak_2p^yc-k_1p^xd=a,这样一来,ab\frac{a}{b} 就是一个可约分的分式,与事实矛盾。证毕。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: 2020牛客暑期多校训练营(第三场)Problem F
Date: 8/15/2020
Description: Number Theory, Construction, Extend Euclid Algorithm
*******************************************************************/
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
const ll top=4000000000000;
void ex_gcd(ll,ll,ll&,ll&);
vector<int> divide(int);
int main(){
int _;
for(cin>>_;_;_--){
int a,b;
ll c,d,e,f;
scanf("%d%d",&a,&b);
int gcd=__gcd(a,b);
if(gcd==1){
vector<int>prime_factor=divide(b);
if(prime_factor.size()<=1){
puts("-1 -1 -1 -1");
}else{
ll p=1;
while(b%p==0){
p=p*prime_factor.front();
}
p/=prime_factor.front();
d=p;
f=b/p;
ex_gcd(f,d,c,e);
c=c*a;
e=-e*a;
ll k=min((top-c)/d,(top-e)/f);
c+=k*d;
e+=k*f;
printf("%lld %lld %lld %lld\n",c,d,e,f);
}
}else{
d=f=b/gcd;
e=1;
c=a/gcd+1;
printf("%lld %lld %lld %lld\n",c,d,e,f);
}
}
return 0;
}
void ex_gcd(ll a,ll b,ll& x,ll& y){
if(!b){
x=1;
y=0;
return;
}else{
ex_gcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
}
}
vector<int> divide(int x){
vector<int>prime_factor;
for(register int i=2;i*i<=x;i++){
if(x%i==0){
prime_factor.push_back(i);
while(x%i==0) x/=i;
}
}
if(x>1) prime_factor.push_back(x);
return prime_factor;
}

L. Problem L is the Only Lovely Problem \looparrowright

题目描述

Dreamoon loves lovely things, like lovely girls, lovely bed sheets, lovely clothes…
So he thinks a string is lovely if and only if it begins with the word “lovely”(case insensitive). You are given a string. Please tell us whether Dreamoon thinks that string is lovely.

输入描述

The input contains only one line.
This line contains a string ss. The length of ss is between 88 and 1010.
ss consists of only the English alphabet. It can be lower case or upper case.

输出描述

If a string is lovely, please output “lovely”, Otherwise, output “ugly”. (The output is case sensitive).

示例1

输入

1
LovelyAA

输出

1
lovely

示例2

输入

1
lovelymoon

输出

1
lovely

示例3

输入

1
NOWCOWDER

输出

1
ugly

示例4

输入

1
LoveLive

输出

1
ugly

分析

要求字符串开头为 “lovely”,只需要依次比较字符串开头的六位即可,只需要注意比较是不区分大小写的。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: 2020牛客暑期多校训练营(第三场) Problem L
Date: 8/14/2020
Description: Easy String Problem
*******************************************************************/
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
int main(){
string s;
cin>>s;
//依次比较6位
//不区分大小写
if((s[0]=='l'||s[0]=='L')&&
(s[1]=='o'||s[1]=='O')&&
(s[2]=='v'||s[2]=='V')&&
(s[3]=='e'||s[3]=='E')&&
(s[4]=='l'||s[4]=='L')&&
(s[5]=='y'||s[5]=='Y')){
puts("lovely");
}else{
puts("ugly");
}
return 0;
}