Codeforces Global Round 2
本来想一场上紫;真没想到结果集体凉凉
A. Ilya and a Colorful Walk
Ilya lives in a beautiful city of Chordalsk.
There are nn houses on the street Ilya lives, they are numerated from 11 to nn from left to right; the distance between every two neighboring houses is equal to 11 unit. The neighboring houses are 11 and 22, 22 and 33, ..., n−1n−1 and nn. The houses nn and 11 are not neighboring.
The houses are colored in colors c1,c2,…,cnc1,c2,…,cn so that the ii-th house is colored in the color cici. Everyone knows that Chordalsk is not boring, so there are at least two houses colored in different colors.
Ilya wants to select two houses ii and jj so that 1≤i<j≤n1≤i<j≤n, and they have different colors: ci≠cjci≠cj. He will then walk from the house iito the house jj the distance of (j−i)(j−i) units.
Ilya loves long walks, so he wants to choose the houses so that the distance between them is the maximum possible.
Help Ilya, find this maximum possible distance.
Input
The first line contains a single integer nn (3≤n≤3000003≤n≤300000) — the number of cities on the street.
The second line contains nn integers c1,c2,…,cnc1,c2,…,cn (1≤ci≤n1≤ci≤n) — the colors of the houses.
It is guaranteed that there is at least one pair of indices ii and jj so that 1≤i<j≤n1≤i<j≤n and ci≠cjci≠cj.
Output
Print a single integer — the maximum possible distance Ilya can walk.
题目大意
找出最大的j-i满足a_j≠a_i,(i<j)。
题目分析
对于a_i≠a_n,就是n-i;对于a_i=a_n,先找出最大的a_pos≠a_n,贡献就是pos-i。
1 #include<bits/stdc++.h> 2 const int maxn = 300035; 3 4 int a[maxn],lst[maxn],ans,n,pos; 5 6 int read() 7 { 8 char ch = getchar(); 9 int num = 0, fl = 1; 10 for (; !isdigit(ch); ch = getchar()) 11 if (ch=='-') fl = -1; 12 for (; isdigit(ch); ch = getchar()) 13 num = (num<<1)+(num<<3)+ch-48; 14 return num*fl; 15 } 16 int main() 17 { 18 n = read(); 19 for (int i=1; i<=n; i++) a[i] = read(), lst[i] = -1; 20 for (int i=1; i<n; i++) 21 if (a[i]!=a[n]) ans = std::max(ans, n-i), pos = i; 22 for (int i=1; i<pos; i++) 23 if (a[i]==a[n]) ans = std::max(ans, pos-i); 24 printf("%d\n",ans); 25 return 0; 26 }
【贪心】B. Alyona and a Narrow Fridge
Alyona has recently bought a miniature fridge that can be represented as a matrix with hh rows and 22 columns. Initially there is only one shelf at the bottom of the fridge, but Alyona can install arbitrary number of shelves inside the fridge between any two rows. A shelf is two cells wide, does not occupy any space but separates the inside of the fridge to the lower and upper part.
![](http://codeforces.com/predownloaded/06/ee/06eeae5a54607cb4cb07894fd1c00bc7c0afe049.png)
Alyona has nn bottles of milk that she wants to put in the fridge. The ii-th bottle is aiai cells tall and 11 cell wide. She can put a bottle on some shelf if the corresponding space above the shelf is at least as tall as the bottle. She can not put a bottle on top of another bottle (if there is no shelf between them). Two bottles can not share a cell.
Alyona is interested in the largest integer kk such that she can put bottles 11, 22, ..., kk in the fridge at the same time. Find this largest kk.
Input
The first line contains two integers nn and hh (1≤n≤1031≤n≤103, 1≤h≤1091≤h≤109) — the number of bottles and the height of the fridge.
The second line contains nn integers a1a1, a2a2, ..., anan (1≤ai≤h1≤ai≤h) — the heights of the bottles.
Output
Print the single integer kk — the maximum integer such that Alyona can put the bottles 11, 22, ..., kk in the fridge at the same time. If Alyona can put all bottles in the fridge, print nn. It is easy to see that Alyona can always put at least one bottle in the fridge.
题目大意
有一个hx2的冰箱,放入物品的规则是:每一层的高度是该层两个(或只放一个)物品的高度最大值,问最多能 按顺序 放进多少物品。
题目分析
自然想到贪心,只需要稍微考虑一下奇数的情况:
当然是第二种情况更优。
1 #include<bits/stdc++.h> 2 const int maxn = 1035; 3 4 int a[maxn],b[maxn],n,h; 5 6 int read() 7 { 8 char ch = getchar(); 9 int num = 0, fl = 1; 10 for (; !isdigit(ch); ch = getchar()) 11 if (ch=='-') fl = -1; 12 for (; isdigit(ch); ch = getchar()) 13 num = (num<<1)+(num<<3)+ch-48; 14 return num*fl; 15 } 16 int main() 17 { 18 n = read(), h = read(); 19 for (int i=1; i<=n; i++) a[i] = read(); 20 for (int i=n; i; i--) 21 { 22 long long tmp = 0; 23 for (int j=1; j<=i; j++) b[j] = a[j]; 24 std::sort(b+1, b+i+1), std::reverse(b+1, b+i+1); 25 for (int j=1,cnt; j<=i; j+=2) 26 { 27 cnt = b[j]; 28 if (j!=i) cnt = std::max(b[j], b[j+1]); 29 tmp += cnt; 30 } 31 if (tmp <= h){ 32 printf("%d\n",i); 33 return 0; 34 } 35 } 36 return 0; 37 }
【思维题】C. Ramesses and Corner Inversion
Ramesses came to university to algorithms practice, and his professor, who is a fairly known programmer, gave him the following task.
You are given two matrices AA and BB of size n×mn×m, each of which consists of 00 and 11 only. You can apply the following operation to the matrix AA arbitrary number of times: take any submatrix of the matrix AA that has at least two rows and two columns, and invert the values in its corners (i.e. all corners of the submatrix that contain 00, will be replaced by 11, and all corners of the submatrix that contain 11, will be replaced by 00). You have to answer whether you can obtain the matrix BB from the matrix AA.
![](http://codeforces.com/predownloaded/3c/f4/3cf4eae1ffbff8f321b3b860413a02f4a8dbfa9e.png)
Ramesses don't want to perform these operations by himself, so he asks you to answer this question.
A submatrix of matrix MM is a matrix which consist of all elements which come from one of the rows with indices x1,x1+1,…,x2x1,x1+1,…,x2 of matrix MM and one of the columns with indices y1,y1+1,…,y2y1,y1+1,…,y2 of matrix MM, where x1,x2,y1,y2x1,x2,y1,y2 are the edge rows and columns of the submatrix. In other words, a submatrix is a set of elements of source matrix which form a solid rectangle (i.e. without holes) with sides parallel to the sides of the original matrix. The corners of the submatrix are cells (x1,y1)(x1,y1), (x1,y2)(x1,y2), (x2,y1)(x2,y1), (x2,y2)(x2,y2), where the cell (i,j)(i,j) denotes the cell on the intersection of the ii-th row and the jj-th column.
Input
The first line contains two integers nn and mm (1≤n,m≤5001≤n,m≤500) — the number of rows and the number of columns in matrices AA and BB.
Each of the next nn lines contain mm integers: the jj-th integer in the ii-th line is the jj-th element of the ii-th row of the matrix AA (0≤Aij≤10≤Aij≤1).
Each of the next nn lines contain mm integers: the jj-th integer in the ii-th line is the jj-th element of the ii-th row of the matrix BB (0≤Bij≤10≤Bij≤1).
Output
Print "Yes" (without quotes) if it is possible to transform the matrix AA to the matrix BB using the operations described above, and "No" (without quotes), if it is not possible. You can print each letter in any case (upper or lower).
题目大意
给定大小相同的矩阵A,B,定义一次操作为选择至少2x2的子矩阵并翻转四个边角元素。问能否通过若干次操作使A变为B。
题目分析
好像是个假题……
我这个暴力复杂度O(kn^4)跑的还挺快。
标算的复杂度就是O(n^2),但是这个n≤500是个什么意思啊
标算的思路是从变化中的不变量:行列的奇偶性 入手。如果注意到奇偶性这点是合法的充要条件,判定就很容易了。
这里是暴力代码:
1 #include<bits/stdc++.h> 2 const int maxn = 503; 3 4 int n,m,a[maxn][maxn]; 5 bool chk; 6 7 int read() 8 { 9 char ch = getchar(); 10 int num = 0, fl = 1; 11 for (; !isdigit(ch); ch = getchar()) 12 if (ch=='-') fl = -1; 13 for (; isdigit(ch); ch = getchar()) 14 num = (num<<1)+(num<<3)+ch-48; 15 return num*fl; 16 } 17 int main() 18 { 19 n = read(), m = read(); 20 for (int i=1; i<=n; i++) 21 for (int j=1; j<=m; j++) 22 a[i][j] = read(); 23 for (int i=1; i<=n; i++) 24 for (int j=1; j<=m; j++) 25 a[i][j] ^= read(); 26 while (true) 27 { 28 bool wat = false; 29 for (int i=2; i<=n; i++) 30 for (int j=1; j<=m; j++) 31 if (a[i][j]){ 32 for (int p=j+1; p<=m; p++) 33 { 34 if (!a[i][j]) break; 35 if (a[i][p]){ 36 for (int l=1; l<i; l++) 37 if (a[l][j]||a[l][p]){ 38 a[l][j] ^= 1, a[l][p] ^= 1; 39 a[i][j] ^= 1, a[i][p] ^= 1; 40 wat = true; 41 break; 42 } 43 } 44 } 45 } 46 if (!wat) break; 47 } 48 chk = true; 49 for (int i=1; i<=n&&chk; i++) 50 for (int j=1; j<=m&&chk; j++) 51 if (a[i][j]) chk = false; 52 puts(!chk?"No":"Yes"); 53 return 0; 54 }
【离线】D. Frets On Fire
Miyako came to the flea kingdom with a ukulele. She became good friends with local flea residents and played beautiful music for them every day.
In return, the fleas made a bigger ukulele for her: it has n strings, and each string has (1018+1) frets numerated from 0 to 1018. The fleas use the array s1,s2,…,sn to describe the ukulele's tuning, that is, the pitch of the j-th fret on the i-th string is the integer si+j.
Miyako is about to leave the kingdom, but the fleas hope that Miyako will answer some last questions for them.
Each question is in the form of: "How many different pitches are there, if we consider frets between l and r (inclusive) on all strings?"
Miyako is about to visit the cricket kingdom and has no time to answer all the questions. Please help her with this task!
Formally, you are given a matrix with n rows and (1018+1) columns, where the cell in the i-th row and j-th column (0≤j≤1018) contains the integer si+j. You are to answer q queries, in the k-th query you have to answer the number of distinct integers in the matrix from the lk-th to the rk-th columns, inclusive.
Input
The first line contains an integer n (1≤n≤100000) — the number of strings.
The second line contains n integers s1,s2,…,sn (0≤si≤1018) — the tuning of the ukulele.
The third line contains an integer q (1≤q≤100000) — the number of questions.
The k-th among the following q lines contains two integers lk,rk (0≤lk≤rk≤1018) — a question from the fleas.
Output
Output one number for each question, separated by spaces — the number of different pitches.
题目大意
有一个列无限的矩阵,每个位置的元素权值vali,j=s_i+j。q次询问求l,r列内不同元素的个数。
题目分析
由于所有元素同时加上[l,r],也即我们只关心r-l。首先求出a_i排序之后相邻元素的差d_i。那么离线之后每一个询问长度len,对于d_i<len,就是len对d_i没有干扰;反之,就是两个a_i“连”了起来存在覆盖。关于这部分的处理,只需要把d_i排个序,离线的时候再线性地扫一趟就好了。
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const int maxn = 100035; 4 5 struct node 6 { 7 ll v,id; 8 node(ll a=0, ll b=0):v(a),id(b) {} 9 bool operator < (node a) const 10 { 11 return v < a.v; 12 } 13 }q[maxn]; 14 int n,m,las; 15 ll ans[maxn],a[maxn],tmp; 16 17 ll read() 18 { 19 char ch = getchar(); 20 ll num = 0, fl = 1; 21 for (; !isdigit(ch); ch = getchar()) 22 if (ch=='-') fl = -1; 23 for (; isdigit(ch); ch = getchar()) 24 num = (num<<1)+(num<<3)+ch-48; 25 return num*fl; 26 } 27 int main() 28 { 29 n = read(); 30 for (int i=1; i<=n; i++) a[i] = read(); 31 std::sort(a+1, a+n+1); 32 m = read(); 33 for (int i=1; i<=m; i++) 34 { 35 ll l = read(), r = read(); 36 q[i] = node(r-l, i); 37 } 38 std::sort(q+1, q+m+1); 39 for (int i=1; i<n; i++) a[i] = a[i+1]-a[i]; 40 las = n, --n; 41 std::sort(a+1, a+n+1); 42 for (int i=1,j=1; i<=m; i++) 43 { 44 for (; q[i].v >= a[j]&&j<=n; j++) 45 tmp += a[j], --las; 46 ans[q[i].id] = tmp+1ll*las*(q[i].v+1); 47 } 48 for (int i=1; i<=m; i++) 49 printf("%lld%c",ans[i],i==m?'\n':' '); 50 return 0; 51 }
【贪心】E. Pavel and Triangles
Pavel has several sticks with lengths equal to powers of two.
He has a0a0 sticks of length 20=120=1, a1a1 sticks of length 21=221=2, ..., an−1an−1 sticks of length 2n−12n−1.
Pavel wants to make the maximum possible number of triangles using these sticks. The triangles should have strictly positive area, each stick can be used in at most one triangle.
It is forbidden to break sticks, and each triangle should consist of exactly three sticks.
Find the maximum possible number of triangles.
Input
The first line contains a single integer nn (1≤n≤3000001≤n≤300000) — the number of different lengths of sticks.
The second line contains nn integers a0a0, a1a1, ..., an−1an−1 (1≤ai≤1091≤ai≤109), where aiai is the number of sticks with the length equal to 2i2i.
Output
Print a single integer — the maximum possible number of non-degenerate triangles that Pavel can make.
题目大意
有n个元素每个元素a_i个,定义合法的三元组是(i,i,i)或者(i,j,j)(i<j),求这些元素的最多合法三元组个数。
题目分析
不错的贪心题。策略是:首选(i,j,j),再把剩下的i尽量选成(i,i,i).
关于证明:
考的时候只想到首选(i,i,i)……
1 #include<bits/stdc++.h> 2 const int maxn = 300035; 3 4 int n,a[maxn]; 5 long long ans,sum,tmp; 6 7 int read() 8 { 9 char ch = getchar(); 10 int num = 0, fl = 1; 11 for (; !isdigit(ch); ch = getchar()) 12 if (ch=='-') fl = -1; 13 for (; isdigit(ch); ch = getchar()) 14 num = (num<<1)+(num<<3)+ch-48; 15 return num*fl; 16 } 17 int main() 18 { 19 n = read(); 20 for (int i=1; i<=n; i++) a[i] = read(); 21 std::reverse(a+1, a+n+1); 22 for (int i=n; i; i--) 23 { 24 tmp = a[i]/2; 25 if (tmp > sum) tmp = sum; 26 ans += tmp; 27 sum -= tmp; 28 a[i] -= tmp*2; 29 ans += a[i]/3, a[i] %= 3; 30 sum += a[i]; 31 } 32 printf("%lld\n",ans); 33 return 0; 34 }
postscript
room里一位灰名小哥A题居然乱二分过了pretest,然而hack被另一位橙名小哥抢走了……(我cf好像都没hack别人几次诶)
考前美好的期待:这把上紫应该没啥问题
然后考后就是集体凉凉了23333
(GlobalRound怎么这么拼手速啊)
话说这题目怎么区分度很差的样子。