Codeforces Round 962 (Div. 3)解题(A-F)

A. Legs

题面翻译

鸡有 2 2 2 条腿,牛有 4 4 4 条腿。现在一共有 n n n 条腿(保证 n n n 是偶数),求最少有多少只动物。

Translated by PineappleSummer.

题目描述

It’s another beautiful day on Farmer John’s farm.

After Farmer John arrived at his farm, he counted $ n $ legs. It is known only chickens and cows live on the farm, and a chicken has $ 2 $ legs while a cow has $ 4 $ .

What is the minimum number of animals Farmer John can have on his farm assuming he counted the legs of all animals?

输入格式

The first line contains single integer $ t $ ( $ 1 \leq t \leq 10^3 $ ) — the number of test cases.

Each test case contains an integer $ n $ ( $ 2 \leq n \leq 2 \cdot 10^3 $ , $ n $ is even).

输出格式

For each test case, output an integer, the minimum number of animals Farmer John can have on his farm.

样例 #1

样例输入 #1

3
2
6
8

样例输出 #1

1
2
2

代码

#include<iostream>

using namespace std;

int T;
int n;

int main(){
    cin>>T;
    
    while(T--){
        cin>>n;
        
        int t=n/4;
        
        cout<<(n-t*4)/2+t<<endl;
    }
    
    return 0;
}

B. Scale

题面翻译

给定 n , k n,k n,k 和一个 n × n n\times n n×n 的网格。

现在要将每 k × k k\times k k×k 个网格变为一个 1 × 1 1\times 1 1×1 的网格,请输出缩小后的网格。

保证 k k k n n n 的因数且每 k × k k\times k k×k 个格子内的数字相同。

Translated by PineappleSummer.

题目描述

Tina has a square grid with $ n $ rows and $ n $ columns. Each cell in the grid is either $ 0 $ or $ 1 $ .

Tina wants to reduce the grid by a factor of $ k $ ( $ k $ is a divisor of $ n $ ). To do this, Tina splits the grid into $ k \times k $ nonoverlapping blocks of cells such that every cell belongs to exactly one block.

Tina then replaces each block of cells with a single cell equal to the value of the cells in the block. It is guaranteed that every cell in the same block has the same value.

For example, the following demonstration shows a grid being reduced by factor of $ 3 $ .

Original grid $ 0 $ $ 0 $ $ 0 $ $ 1 $ $ 1 $ $ 1 $ $ 0 $ $ 0 $ $ 0 $ $ 1 $ $ 1 $ $ 1 $ $ 0 $ $ 0 $ $ 0 $ $ 1 $ $ 1 $ $ 1 $ $ 1 $ $ 1 $ $ 1 $ $ 0 $ $ 0 $ $ 0 $ $ 1 $ $ 1 $ $ 1 $ $ 0 $ $ 0 $ $ 0 $ $ 1 $ $ 1 $ $ 1 $ $ 0 $ $ 0 $ $ 0 $ Reduced grid $ 0 $ $ 1 $ $ 1 $ $ 0 $ Help Tina reduce the grid by a factor of $ k $ .

输入格式

The first line contains $ t $ ( $ 1 \leq t \leq 100 $ ) – the number of test cases.

The first line of each test case contains two integers $ n $ and $ k $ ( $ 1 \leq n \leq 1000 $ , $ 1 \le k \le n $ , $ k $ is a divisor of $ n $ ) — the number of rows and columns of the grid, and the factor that Tina wants to reduce the grid by.

Each of the following $ n $ lines contain $ n $ characters describing the cells of the grid. Each character is either $ 0 $ or $ 1 $ . It is guaranteed every $ k $ by $ k $ block has the same value.

It is guaranteed the sum of $ n $ over all test cases does not exceed $ 1000 $ .

输出格式

For each test case, output the grid reduced by a factor of $ k $ on a new line.

样例 #1

样例输入 #1

4
4 4
0000
0000
0000
0000
6 3
000111
000111
000111
111000
111000
111000
6 2
001100
001100
111111
111111
110000
110000
8 1
11111111
11111111
11111111
11111111
11111111
11111111
11111111
11111111

样例输出 #1

0
01
10
010
111
100
11111111
11111111
11111111
11111111
11111111
11111111
11111111
11111111

代码

#include<iostream>

using namespace std;

const int N = 1010;

char w[N][N];
int T;
int n,k;

int main(){
    cin>>T;
    
    while(T--){
        cin>>n>>k;
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>w[i][j];
            }
        }
        
        if(k==1){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    cout<<w[i][j];
                }
                cout<<endl;
            }
        }else{
            // int t=n/k;
            
            for(int i=1;i<=n;i+=k){
                for(int j=1;j<=n;j+=k){
                    cout<<w[i][j];
                }
                cout<<endl;
            }
        }
        
        
    }
    
    return 0;
}

C. Sort

题面翻译

给出两个长度为 n n n 的字符串 a a a b b b。有 q q q 组询问,对于每个询问,给出一个区间 [ l , r ] [l,r] [l,r]

在一次操作中,可以选择一个位置 i ( l ≤ i ≤ r ) i(l \leq i \leq r) i(lir),并将 a i a_i ai 改变为任意字符。输出使得 sorted(a[l..r]) = sorted(b[l..r]) \texttt{sorted(a[l..r])} = \texttt{sorted(b[l..r])} sorted(a[l..r])=sorted(b[l..r]) 的最小操作数。

对于任意字符串 c c c sorted(c[l..r]) \texttt{sorted(c[l..r])} sorted(c[l..r]) 表示由字符 c l , c l + 1 , … , c r c_l, c_{l+1}, \ldots , c_r cl,cl+1,,cr 按字典序排序组成的子串。

∑ n , q ≤ 2 × 1 0 5 \sum n,q\le 2\times 10^5 n,q2×105,字符串中仅包含小写英文字母。每组询问相互独立。

Translated by PineappleSummer.

题目描述

You are given two strings $ a $ and $ b $ of length $ n $ . Then, you are (forced against your will) to answer $ q $ queries.

For each query, you are given a range bounded by $ l $ and $ r $ . In one operation, you can choose an integer $ i $ ( $ l \leq i \leq r $ ) and set $ a_i = x $ where $ x $ is any character you desire. Output the minimum number of operations you must perform such that $ \texttt{sorted(a[l…r])} = \texttt{sorted(b[l…r])} $ . The operations you perform on one query does not affect other queries.

For an arbitrary string $ c $ , $ \texttt{sorted(c[l…r])} $ denotes the substring consisting of characters $ c_l, c_{l+1}, … , c_r $ sorted in lexicographical order.

输入格式

The first line contains $ t $ ( $ 1 \leq t \leq 1000 $ ) – the number of test cases.

The first line of each test case contains two integers $ n $ and $ q $ ( $ 1 \leq n, q \leq 2 \cdot 10^5 $ ) – the length of both strings and the number of queries.

The following line contains $ a $ of length $ n $ . It is guaranteed $ a $ only contains lowercase latin letters.

The following line contains $ b $ of length $ n $ . It is guaranteed $ b $ only contains lowercase latin letters.

The following $ q $ lines contain two integers $ l $ and $ r $ ( $ 1 \leq l \leq r \leq n $ ) – the range of the query.

It is guaranteed the sum of $ n $ and $ q $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each query, output an integer, the minimum number of operations you need to perform in a new line.

样例 #1

样例输入 #1

3
5 3
abcde
edcba
1 5
1 4
3 3
4 2
zzde
azbe
1 3
1 4
6 3
uwuwuw
wuwuwu
2 4
1 3
1 6

样例输出 #1

0
1
0
2
2
1
1
0

提示

For the first query, $ \texttt{sorted(a[1…5])} = $ abcde and $ \texttt{sorted(b[1…5])} = $ abcde, so no operations are necessary.

For the second query, you need to set $ a_1 = $ e. Then, $ \texttt{sorted(a[1…4])} = \texttt{sorted(b[1…4])} = $ bcde.

思路

这道题我最开始做的是用暴力,没想到 TLE #6,此时我们就得考虑优化。

因为每次排序其实看的就是在一段子区间不同字母的个数,那么这个我们可以预处理下。

#include<iostream>
#include<algorithm>
#include<map>

using namespace std;

const int N = 2e5+10;

int a[N],b[N];
int T;
int n,q;
int f1[N][30],f2[N][30];

int main(){
    cin>>T;
    
    while(T--){
        cin>>n>>q;
        
        for(int i=1;i<=n;i++){
            char x;
            cin>>x;
            a[i]=x-'a';
        }
        for(int i=1;i<=n;i++){
            char x;
            cin>>x;
            b[i]=x-'a';
        }
        
        for(int i=1;i<=n;i++){
            for(int j=0;j<26;j++){
                f1[i][j]=f1[i-1][j]+(a[i]==j);
                f2[i][j]=f2[i-1][j]+(b[i]==j);
            }
        }
        
        
        while(q--){
            int l,r;
            cin>>l>>r;
            
            int cnt=0;
            
            for(int i=0;i<26;i++){
                cnt+=abs(f1[r][i]-f1[l-1][i]-f2[r][i]+f2[l-1][i]);
            }
            cout<<cnt/2<<endl;
        }
        
    }
    return 0;
}

D. Fun

题面翻译

Counting is Fun!

给定两个整数 n n n x x x 1 ≤ n , x ≤ 1 0 6 1\le n,x\le 10^6 1n,x106),求满足 a b + a c + b c ≤ n ab + ac + bc \le n ab+ac+bcn a + b + c ≤ x a + b + c \le x a+b+cx正整数三元组 ( a , b , c ) (a,b,c) (a,b,c) 的个数。

请注意,三元组是有序的。例如, ( 1 , 1 , 2 ) (1, 1, 2) (1,1,2) ( 1 , 2 , 1 ) (1, 2, 1) (1,2,1) 是不同的三元组。 a , b , c a,b,c a,b,c 必须严格大于 0 0 0

Translated by PineappleSummer.

题目描述

Counting is Fun!

— satyam343

Given two integers $ n $ and $ x $ , find the number of triplets ( $ a,b,c $ ) of positive integers such that $ ab + ac + bc \le n $ and $ a + b + c \le x $ .

Note that order matters (e.g. ( $ 1, 1, 2 $ ) and ( $ 1, 2, 1 $ ) are treated as different) and $ a $ , $ b $ , $ c $ must be strictly greater than $ 0 $ .

输入格式

The first line contains a single integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases.

Each test case contains two integers $ n $ and $ x $ ( $ 1 \leq n,x \leq 10^6 $ ).

It is guaranteed that the sum of $ n $ over all test cases does not exceed $ 10^6 $ and that the sum of $ x $ over all test cases does not exceed $ 10^6 $ .

输出格式

Output a single integer — the number of triplets ( $ a,b,c $ ) of positive integers such that $ ab + ac + bc \le n $ and $ a + b + c \le x $ .

样例 #1

样例输入 #1

4
7 4
10 5
7 1000
900000 400000

样例输出 #1

4
10
7
1768016938

提示

In the first test case, the triplets are ( $ 1, 1, 1 $ ), ( $ 1, 1, 2 $ ), ( $ 1, 2, 1 $ ), and ( $ 2, 1, 1 $ ).

In the second test case, the triplets are ( $ 1, 1, 1 $ ), ( $ 1, 1, 2 $ ), ( $ 1, 1, 3 $ ), ( $ 1, 2, 1 $ ), ( $ 1, 2, 2 $ ), ( $ 1, 3, 1 $ ), ( $ 2, 1, 1 $ ), ( $ 2, 1, 2 $ ), ( $ 2, 2, 1 $ ), and ( $ 3, 1, 1 $ ).

思路

这道题思路也很简单,我们可以暴力枚举,我们可以很快的得出:

1 ≤ a ≤ x 1\le a\le x 1ax
1 ≤ a b ≤ n 1\le ab\le n 1abn
1 ≤ c ≤ m i n ( n − a − b , ( n − a b ) / ( a + b ) 1\le c\le min(n-a-b,(n-ab)/(a+b) 1cmin(nab,(nab)/(a+b)

那么代码也就很好写了:

  • 注意:开long long。
//先枚举a,再美剧b,最后c

#include<iostream>

#define int long long

using namespace std;

int n,x;
int T;

signed main(){
    cin>>T;
    
    while(T--){
        cin>>n>>x;
        
        int cnt=0;
        for(int a=1;a<=x;a++){
            for(int b=1;b*a<=n&&a+b<=x;b++){
                cnt+=min((n-a*b)/(a+b),x-a-b);
            }
        }
        cout<<cnt<<endl;
    }
    
    return 0;
}

E. Decode

题面翻译

给出一个长度为由 0 0 0 1 1 1 组成的字符串 s s s

定义:若区间 [ l , r ] [l,r] [l,r] 0 0 0 的个数等于 1 1 1 的个数,则 f ( l , r ) = 1 f(l,r)=1 f(l,r)=1,否则 f ( l , r ) = 0 f(l,r)=0 f(l,r)=0

∑ l = 1 n ∑ r = l n ∑ x = l r ∑ y = x r f ( x , y ) \displaystyle\sum_{l=1}^n \displaystyle\sum_{r=l}^n\displaystyle\sum_{x=l}^r \displaystyle\sum_{y=x}^r f(x,y) l=1nr=lnx=lry=xrf(x,y)

答案对 1 0 9 + 7 10^9+7 109+7 取模。

∣ s ∣ |s| s 为字符串 s s s 的长度,保证 1 ≤ ∣ s ∣ ≤ 2 × 1 0 5 1\le |s|\le 2\times 10^5 1s2×105

Translated by PineappleSummer.

题目描述

In a desperate attempt to obtain your waifu favorite character, you have hacked into the source code of the game. After days of struggling, you finally find the binary string that encodes the gacha system of the game. In order to decode it, you must first solve the following problem.

You are given a binary string $ s $ of length $ n $ . For each pair of integers $ (l, r) $ $ (1 \leq l \leq r \leq n) $ , count the number of pairs $ (x, y) $ $ (l \leq x \leq y \leq r) $ such that the amount of $ \mathtt{0} $ equals the amount of $ \mathtt{1} $ in the substring $ s_xs_{x+1}…s_y $ .

Output the sum of counts over all possible $ (l, r) $ modulo $ 10^9+7 $ .

输入格式

The first line contains $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

Each test case contains a binary string $ s $ ( $ 1 \leq |s| \leq 2 \cdot 10^5 $ ). It is guaranteed $ s $ only contains characters $ \mathtt{0} $ and $ \mathtt{1} $ .

It is guaranteed the sum of $ |s| $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output an integer, the answer modulo $ 10^9+7 $ .

样例 #1

样例输入 #1

4
0000
01010101
1100111001
11000000111

样例输出 #1

0
130
147
70

思路

对于这种01串的,叫我们求子串的0的个数1的个数,我们可以用前缀和来维护,如果是1的话,我们就+1,反之-1,那么这样如果相等的话,此时就是等于0。因为题目枚举的是 x , y x,y x,y,然后里面又叫我们求 ( l , r ) (l,r) (l,r) 满足的个数,我们就干脆直接枚举 ( l , r ) (l,r) (l,r),最后扩大 x , y x,y x,y(也就是举个例子,如果我 ( x + 1 , y ) (x+1,y) (x+1,y) 满足条件的话,那么我们区间外的子区间也不就满足条件吗),因此我们可以直接求 ∑ ( x + 1 ) ( n − y + 1 ) \sum (x+1)(n-y+1) (x+1)(ny+1),我们可以先枚举 x x x(也就是固定 x x x),去看 y y y 。为了加速计算,我们用 map 来存储。

为什么 map 能加速计算,可以看:
在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<map>

#define int long long

using namespace std;

const int N = 2e5+10,mod=1e9+7;

string a;
int T;

signed main(){
    cin>>T;
    
    while(T--){
        cin>>a;
        int n=a.size();
        a=' '+a;
        map<int,int>num;
        num[0]=1;
        int cnt=0,res=0;
        for(int i=1;i<=n;i++){
            if(a[i]=='1')cnt++;
            else cnt--;
            (res+=num[cnt]*(n-i+1))%=mod;
            (num[cnt]+=i+1)%=mod;
        }        
        cout<<res%mod<<endl;
    }
    
    return 0;
}

F. Bomb

题面翻译

题目描述

你有两个长度为 n n n 的数组 a a a b b b。最初,你的分数是 0 0 0。每一次操作中,你可以选择一个 a i a_i ai 加到你的分数上。然后 a i a_i ai 将会更新为 max ⁡ ( 0 , a i − b i ) \max(0,a_i-b_i) max(0,aibi)

现在你只能执行 k k k 次操作。那么你能得到的最大分数是多少?

输入格式

本题每个测试点包含多组数据

每个测试数据的第一行输入 t ( 1 ≤ t ≤ 1000 ) t(1 \le t \le 1000) t(1t1000) 表示数据组数。

每组数据的第一行包含两个整数 n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n(1 \le n \le 2 \cdot 10^5) n(1n2105) k ( 1 ≤ k ≤ 1 0 9 ) k(1 \le k \le 10^9) k(1k109)。分别表示两个数组的长度以及操作次数。

接下来的 2 2 2 行,分别输入数组 a a a b ( 1 ≤ a i , b i ≤ 1 0 9 ) b(1 \le a_i,b_i \le 10^9) b(1ai,bi109)

保证每个测试数据中 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

输出格式

t t t 行,第 i i i 行表示第 i i i 组数据执行 k k k 次操作后分数的最大值。

题目描述

Sparkle gives you two arrays $ a $ and $ b $ of length $ n $ . Initially, your score is $ 0 $ . In one operation, you can choose an integer $ i $ and add $ a_i $ to your score. Then, you must set $ a_i $ = $ \max(0, a_i - b_i) $ .

You only have time to perform $ k $ operations before Sparkle sets off a nuclear bomb! What is the maximum score you can acquire after $ k $ operations?

输入格式

The first line contains $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

The first line of each test case contains $ n $ and $ k $ ( $ 1 \leq n \leq 2 \cdot 10^5, 1 \leq k \leq 10^9 $ ) — the length of the arrays and the number of operations you can perform.

The following line contains $ n $ integers $ a_1, a_2, … a_n $ ( $ 1 \leq a_i \leq 10^9 $ ).

The following line contains $ n $ integers $ b_1, b_2, … b_n $ ( $ 1 \leq b_i \leq 10^9 $ ).

It is guaranteed that the sum of $ n $ for all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output an integer, the maximum score you can acquire after $ k $ operations.

样例 #1

样例输入 #1

5
3 4
5 6 7
2 3 4
5 9
32 52 68 64 14
18 14 53 24 8
5 1000
1 2 3 4 5
5 4 3 2 1
1 1000000
1000000
1
10 6
3 3 5 10 6 8 6 8 7 7
6 1 7 4 1 1 8 9 3 1

样例输出 #1

21
349
27
500000500000
47

思路

根据题意,我们可以知道我们每次是求最大的,因此我们最开始能想到用堆来维护,但由于时间复杂度过高,我们只好换一种思路。

我们要求最大的,我们还可以用二分,也就是就是二分答案寻找一个 x x x,使得在有限次选择和操作过程中都不会使用比 x x x 更小的数。

因为 a[i]=max(0,a[i]-b[i]),因此我们可以算 a 一共要进行多少次操作,这个怎么算呢?我们可以 (a[i]-x)/b[i]+1) 来计算。

然后我们通过这个 x x x 来计算价值。

#include<iostream>
#include<queue>

#define int long long

using namespace std;

const int N = 2e5+10;

int T;
int n,k;
int a[N],b[N];

bool check(int x){
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(a[i]>=x)cnt+=(a[i]-x)/b[i]+1;//用多少次很经常这么写
        //a[i]、a[i]-b[i]、…,即对于当前枚举的a[i],其可得到的≥x的数中一共有(a[i]-x)/b[i]+1个,即进行了(a[i]-x)/b[i]+1次操作
    }
    return cnt>=k;
}

signed main(){
    cin>>T;
    
    while(T--){
        cin>>n>>k;
        
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)cin>>b[i];
        
        int l=0,r=2e9;
        
        while(l+1!=r){
            int mid=l+r>>1;
            if(check(mid))l=mid;
            else r=mid;
        }
        
        int res=0,sum=0;
        
        //验证操作
        for(int i=1;i<=n;i++){
            int cnt=0;
            if(a[i]>=l)cnt+=(a[i]-l)/b[i]+1;
            int p=a[i]-(cnt-1)*b[i];//p表示a[i]递减操作过程中最后一个≥x的数的具体值
            sum+=(p+a[i])*cnt/2;
            res+=cnt;
        }
        
        cout<<sum+l*(k-res)<<endl;
        
    }
    return 0;
}//yyds

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值