Codeforces Round #506 (Div. 3)ABCDEF

并没有参加比赛,全是赛后AC

A题

  题意:现有一个长度为n的字符串s。你需要构建一个长度最小的字符串t,使得t中恰好包含k个s(允许部分重叠),输出这个字符串

  

 1 /*
 2     我们可以非常容易的发现我们构造出来的字符串t有着鲜明的特征。即t中有大量重复的子串,可以证明的是t = S + (K-1)*A, A是S串中删去一段字符串(这段字符串满足既是S的前缀又是S的后缀)。
 3 */
 4 #include<cstdio>
 5 #include<iostream>
 6
 7 using namespace std;
 8
 9 const int maxn = 50 + 5;
10
11 char a[maxn];
12 int n, k;
13
14 int main(void) {
15     scanf("%d%d", &n, &k);
16     scanf("%s", a + 1);
17     string s1 = "", s2 = ""; int res = 0;
18     for (int i = 1, j = n; i < n; ++ i, -- j) {
19         s1 = s1 + a[i];
20         s2 = a[j] + s2;
21         if (s1 == s2) res = max(res, i);
22     }
23     int len = n - res;
24 //    cout << len << endl;
25     string ans = "";
26     for (int i = n; i >= n - len + 1; -- i) ans = a[i] + ans;
27     for (int i = 1; i <= n; ++ i) printf("%c", a[i]);
28     for (int i = 1; i < k; ++ i) cout << ans; puts("");
29     return 0;
30 }

B题

  题意:给出一个长度为n的数组A,数组A中的元素a[i]满足(1<=a[i]<=10^9),且a[i]严格大于a[i-1](2<=i<=n)。现在要你找出一个数组B,满足数组B中所有元素在A中都是有序排列的,即B是A的非连续子序列,数组B中的元素要满足b[i]>=2*b[i-1],输出这个数组B的最大长度。

 1 /*
 2 一个类似导弹拦截的DP+决策单调性优化(这个优化由单调队列实现)
 3 */
 4 #include<cstdio>
 5 #include<algorithm>
 6
 7 using namespace std;
 8
 9 const int maxn = 2e5 + 5;
10
11 int n, a[maxn], f[maxn], Stack[maxn], val[maxn];
12
13
14 int main(void) {
15     scanf("%d", &n);
16     for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
17     int L = 1, R = 1;
18     Stack[1] = 1;
19     val[1] = 1;
20     int ans = 1;
21     // a值小f值大 和 a值大f值小
22     for (int i = 2; i <= n; ++ i) {
23         while (L <= R && a[Stack[L]] * 2 < a[i]) ++ L;
24         if (L <= R) {
25             int cur = val[L] + 1;
26             ans = max(ans, cur);
27             while (L <= R && cur >= val[R]) -- R;
28             ++ R; Stack[R] = i; val[R] = cur;
29         } else {
30             int cur = 1;
31             ++ R; Stack[R] = i; val[R] = cur;
32         }
33     }
34     printf("%d\n", ans);
35     return 0;
36 }

C题:

  题意:给出n个区间(2<=n<=3e5),区间的左右边界均在[0,1e9]之间,现要你去掉一个区间,求出剩下n-1个区间的区间交,使得这个区间交的长度最大。输出这个长度

 1 /*
 2     我们维护两个东西,一个是区间并的前缀f[i],另一个是区间并的后缀g[i]。如果我们去掉i这个区间,答案就是f[i-1]这个区间和g[i+1]这个区间的区间并。
 3
 4 */
 5 #include<bits/stdc++.h>
 6
 7 using namespace std;
 8
 9 const int maxn = 3e5 + 5;
10
11 int n, l[maxn], r[maxn];
12
13 struct node {
14     int l, r;
15 } f[maxn], g[maxn];
16
17 pair<int, int> Make(int l0, int r0, int l1, int r1) {
18     if (l0 > l1) {
19         swap(l0, l1); swap(r0, r1);
20     }
21     // [l0, r0] [l1, r1]  l0 <= l1
22     if (r0 <= l1) return make_pair(-1, -1);
23     if (r0 >= r1) return make_pair(l1, r1);
24     return make_pair(l1, r0);
25 } // 输入两个区间,返回他们的并区间
26
27 int Get_Ans(pair<int, int> tmp) {
28     return tmp.second - tmp.first;
29 } //得到区间tmp的长度。
30
31 int main(void) {
32     scanf("%d", &n);
33     for (int i = 1; i <= n; ++ i) scanf("%d%d", &l[i], &r[i]);
34
35     int L = l[1], R = r[1];
36     f[1].l = L; f[1].r = R;
37     for (int i = 2; i <= n; ++ i) {
38         pair<int, int> tmp = Make(L, R, l[i], r[i]);
39         L = f[i].l = tmp.first;    R = f[i].r = tmp.second;
40     }
41
42     L = l[n]; R = r[n];
43     g[n].l = L; g[n].r = R;
44     for (int i = n - 1; i >= 1; -- i) {
45         pair<int, int> tmp = Make(L, R, l[i], r[i]);
46         L = g[i].l = tmp.first; R = g[i].r = tmp.second;
47     }
48
49     int ans = max(Get_Ans(make_pair(g[2].l, g[2].r)), Get_Ans(make_pair(f[n - 1].l, f[n - 1].r)));
50
51     for (int i = 2; i < n; ++ i) {
52         ans = max(ans, Get_Ans(Make(f[i - 1].l, f[i - 1].r, g[i + 1].l, g[i + 1].r)));
53     }
54     printf("%d\n", ans);
55     return 0;
56 }

原文地址:https://www.cnblogs.com/juruohx/p/9580562.html

时间: 2024-07-30 03:42:29

Codeforces Round #506 (Div. 3)ABCDEF的相关文章

Codeforces Round #506 (Div. 3) D-F

Codeforces Round #506 (Div. 3) (中等难度) 自己的做题速度大概只尝试了D题,不过TLE D. Concatenated Multiples 题意 数组a[],长度n,给一个数k,求满足条件的(i,j)(i!=j) a[i],a[j]连起来就可以整除k 连起来的意思是 20,5连起来时205; 5,20连起来时520 n<=2*1e5,k<=1e9,ai<=1e9 愚蠢的思路是像我一样遍历(i,j)可能性,然后TLE,因为这是O(n^2) 可以先思考一简单问

Codeforces Round #506 (Div. 3) 题解

Codeforces Round #506 (Div. 3) 题目总链接:https://codeforces.com/contest/1029 A. Many Equal Substrings 题意: 给出长度为n的字符串,然后要求你添加一些字符,使得有k个这样的字符串. 题解: 直接暴力吧...一个指针从1开始,另一个从2开始,逐一比较看是否相同:如果不同,第一个指针继续回到1,第二个指针从3开始...就这么一直重复.最后如果第二个指针能够顺利到最后一位,那么记录当前的第一个指针,把他后面的

Codeforces Round #506 (Div. 3) C. Maximal Intersection

C. Maximal Intersection time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output You are given nn segments on a number line; each endpoint of every segment has integer coordinates. Some segments ca

Codeforces Round #506 (Div. 3) A-C

CF比赛题解(简单题) 简单题是指自己在比赛期间做出来了 A. Many Equal Substrings 题意 给个字符串t,构造一个字符串s,使得s中t出现k次;s的长度最短 如t="cat",k=3, minlen(s)=9,s=catcatcat 1<=len(t),k<=50 题解 稍加思考是个前缀等于后缀的问题,用kmp的next数组模板 假设t[0..l-1]==t[n-l....n-1] 那么应该不断重复t[l...n-1]这样的子串 代码如下(应该好好记住

Codeforces Round #506 (Div. 3) C. Maximal Intersection (枚举)

[题目描述] You are given $n$ segments on a number line; each endpoint of every segment has integer coordinates. Some segments can degenerate to points. Segments can intersect with each other, be nested in each other or even coincide. The intersection of

Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta&#39;s Colorful Graph【并查集】

题目链接:http://codeforces.com/problemset/problem/506/D 题目大意: 给出n个顶点,m条边,每条边上有一个数字,代表某个颜色.不同数字代表不同的颜色.有很多个询问,每个询问问有多少条纯种颜色的路径使得某两个点联通. 分析: 这个题一看就想用并查集来搞,每种颜色用一个并查集处理.对于输入的每条边,我们只需要将这两个点在这条边的颜色对应的并查集中合并就好了.查询的时候,我们只需要检测这两个点在多少个颜色对应的并查集中是在统一集合中的,那么就有多少条纯种颜

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我