ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3)

2019-11-24 21:01:18  阅读:307  来源: 互联网

标签:10 based 602 int void while putchar Round getchar


A.Math Problem(CF 1262 A)

题目大意:给定n条线段,求一条线段,使得这个线段能够跟所有给定的线段都相交(端点值一样也算相交),最小化它的长度,可以是0.

很显然找出这n条线段的左端点最大值和右端点的最小值,它们的差和0的最大值即为答案。

 

 1 #include <bits/stdc++.h>
 2 #define MIN(a,b) (((a)<(b)?(a):(b)))
 3 #define MAX(a,b) (((a)>(b)?(a):(b)))
 4 using namespace std;
 5 
 6 template <typename T>
 7 void read(T &x) {
 8     int s = 0, c = getchar();
 9     x = 0;
10     while (isspace(c)) c = getchar();
11     if (c == 45) s = 1, c = getchar();
12     while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
13     if (s) x = -x;
14 }
15 
16 template <typename T>
17 void write(T x, char c = ' ') {
18     int b[40], l = 0;
19     if (x < 0) putchar(45), x = -x;
20     while (x > 0) b[l++] = x % 10, x /= 10;
21     if (!l) putchar(48);
22     while (l) putchar(b[--l] | 48);
23     putchar(c);
24 }
25 
26 void Input(void) {
27     int n,l,r;
28     l=0;
29     r=1e9+7;
30     read(n);
31     for(int u,v,i=1;i<=n;++i){
32         read(u);
33         read(v);
34         l=MAX(l,u);
35         r=MIN(v,r);
36     }
37     printf("%d\n",MAX(l-r,0));
38 }
39 
40 void Solve(void) {}
41 
42 void Output(void) {}
43 
44 main(void) {
45     int kase;
46     freopen("input.txt", "r", stdin);
47     freopen("output.txt", "w", stdout);
48     read(kase);
49     for (int i = 1; i <= kase; i++) {
50         //printf("Case #%d: ", i);
51         Input();
52         Solve();
53         Output();
54     }
55 }
神奇的代码

 

B.Box(CF 1262 B)

题目大意:给出一个排列每一个位置的前缀最大值,还原该排列,答案可能有多种,还原任意一种即可。

输入max[i],如果max[i-1]<max[i],则第i位一定是max[i].

如果max[i-1]=max[i],则我们可以选择小于max[i]的未出现的数作为第i位,贪心构造即可。当没有数可以选择的时候则说明没有排列满足该条件。

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 template <typename T>
 5 void read(T &x) {
 6     int s = 0, c = getchar();
 7     x = 0;
 8     while (isspace(c)) c = getchar();
 9     if (c == 45) s = 1, c = getchar();
10     while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
11     if (s) x = -x;
12 }
13 
14 template <typename T>
15 void write(T x, char c = ' ') {
16     int b[40], l = 0;
17     if (x < 0) putchar(45), x = -x;
18     while (x > 0) b[l++] = x % 10, x /= 10;
19     if (!l) putchar(48);
20     while (l) putchar(b[--l] | 48);
21     putchar(c);
22 }
23 int n,l,ans[100050];
24 bool used[100050];
25 void Input(void) {
26     read(n);
27     for(int i=1;i<=n;++i) used[i]=true;
28     l=1;
29     ans[0]=0;
30     bool qwq=false;
31     for(int u,v=0,i=1;i<=n;++i){
32         read(u);
33         if (qwq) continue;
34         if (u>v){
35             used[u]=false;
36             ans[i]=u;
37             v=u;
38             continue;
39         }
40         while(l<u&&used[l]==false) ++l;
41         if (l==u){
42             qwq=true;
43             continue;
44         }
45         ans[i]=l;
46         used[l]=false;
47     }
48     if (qwq) printf("-1\n");
49     else{
50         for(int i=1;i<=n;++i) printf("%d%c",ans[i],i==n?'\n':' ');
51     }
52 }
53 
54 void Solve(void) {}
55 
56 void Output(void) {}
57 
58 main(void) {
59     int kase;
60     freopen("input.txt", "r", stdin);
61     freopen("output.txt", "w", stdout);
62     read(kase);
63     for (int i = 1; i <= kase; i++) {
64         //printf("Case #%d: ", i);
65         Input();
66         Solve();
67         Output();
68     }
69 }
神奇的代码

 

C.Messy

题目大意:给定一个括号串,我们可以翻转某一区间的括号,即对[l...r]翻转,则变成[r...l],然后我们需要进行不超过n次操作,使得该括号串合法,且对于所有该串的前缀子串,有k个合法子串,输出操作次数以及前后分别进行的操作的区间的左端点和右端点,注意只要小于n即可,不需要最小。题目保证有解。

 

所有子串有k个合法前缀子串,即整个子串分成了k份,我们对某一份中的()交换,则将该份子串拆成两份,我们把两份子串的接触点)(交换,则这两个子串合并成一个,所以我们关键是如何让该子串合法,然后就不会了qwq

坑待填

 

 

D.Optimal Subsequences(CF 1262 D1、D2)

题目大意:给定一个长度为n的数组,求一个长度为k的最佳序列,该序列满足两个条件:其和是所有长度相同的序列的和的最大值;该序列是所有长度相同且和最大的序列中,其数字构成的序列的字典序最小,输出该序列的第pos位的数字,多次询问。

很容易想到我们可以先对k进行从小到大排序,依次构造出长度为k的最佳序列,其构造方法很容易想到,即设最佳序列的数组为a,数大的先添加进a数组,数相等的位置在前的先添加。

但关键在于如何找到该序列中第pos位的数字。

我们新设一个数组cnt,cnt[i]表示第i个数字被选中了,记为1,否则为0,然后我们用树状数组来维护cnt数组的前缀和,当某位的前缀和为pos,且该位被选中了,则该位的数字即为所求答案。由于前缀和单调递增,我们可以采用二分,即可在O(log2n)时间内找出。

总时间复杂度是O(mlog2n+mlogm)

 

当时做的时候逆过来,k从大到小排序,然后在原数组删数,树状数组维护前i个数中被删去的个数,则对于在原数组第i位且未被删去的数,它在最佳序列的位置即为i-sum[i],同样二分找即可。

  1 #include <bits/stdc++.h>
  2 #define lowbit(x)  ((x&(-x)))
  3 using namespace std;
  4 
  5 template <typename T>
  6 void read(T &x) {
  7     int s = 0, c = getchar();
  8     x = 0;
  9     while (isspace(c)) c = getchar();
 10     if (c == 45) s = 1, c = getchar();
 11     while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
 12     if (s) x = -x;
 13 }
 14 
 15 template <typename T>
 16 void write(T x, char c = ' ') {
 17     int b[40], l = 0;
 18     if (x < 0) putchar(45), x = -x;
 19     while (x > 0) b[l++] = x % 10, x /= 10;
 20     if (!l) putchar(48);
 21     while (l) putchar(b[--l] | 48);
 22     putchar(c);
 23 }
 24 
 25 struct data{
 26     int val,id;
 27     bool operator < (const data &b) const{
 28         if (val>b.val) return true;
 29         if (val<b.val) return false;
 30         if (id<b.id) return true;
 31         return false;
 32     }
 33 };
 34 
 35 const int N=2e5+5;
 36 
 37 struct date{
 38     int k,pos,id;
 39 }que[N];
 40 
 41 priority_queue<data> qwq;
 42 
 43 int n,m;
 44 
 45 int tree[N],a[N],ans[N];
 46 
 47 bool dell[N];
 48 
 49 bool cmp(const struct date &a,const struct date &b){
 50     if (a.k>b.k) return true;
 51     if (a.k<b.k) return false;
 52     if (a.pos<b.pos) return false;
 53     return true;
 54 }
 55 
 56 void Input(void) {
 57     read(n);
 58     for(int i=1;i<=n;++i) {
 59         read(a[i]);
 60         qwq.push(data{a[i],i});
 61     }
 62     read(m);
 63     for(int i=1;i<=m;++i){
 64         que[i].id=i;
 65         read(que[i].k);
 66         read(que[i].pos);
 67     }
 68 }
 69 
 70 void tree_insert(int x){
 71     for(int i=x;i<=n;i+=lowbit(i))
 72         tree[i]++;
 73 }
 74 
 75 int tree_sum(int x){
 76     int a=0;
 77     for(int i=x;i>=1;i-=lowbit(i))
 78         a+=tree[i];
 79     return a;
 80 }
 81 
 82 int find_pos(int x){
 83     int l=1,r=n;
 84     while(l<=r){
 85         int mid=(l+r)>>1;
 86         int tmp=tree_sum(mid);
 87         if (mid-tmp>x) r=mid;
 88         else if (mid-tmp==x) if (dell[mid]==false) return a[mid];
 89         else r=mid;
 90         else l=mid+1;
 91     }
 92     return 0;
 93 } 
 94 
 95 void Solve(void) {
 96     sort(que+1,que+1+m,cmp);
 97     int qvq=n;
 98     for(int i=1;i<=m;++i){
 99         int dis=qvq-que[i].k;
100         qvq=que[i].k;
101         while(dis--){
102             data qaq=qwq.top();
103             dell[qaq.id]=true;
104             tree_insert(qaq.id);
105             qwq.pop();
106         }
107         ans[que[i].id]=find_pos(que[i].pos);
108     }
109 }
110 
111 void Output(void) {
112     for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
113 }
114 
115 main(void) {
116     freopen("input.txt", "r", stdin);
117     freopen("output.txt", "w", stdout);
118     Input();
119     Solve();
120     Output();
121 }
神奇的代码

(以为会T的结果才跑了200+ms?)

 

标签:10,based,602,int,void,while,putchar,Round,getchar
来源: https://www.cnblogs.com/Lanly/p/11924231.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有