Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)

考场上只做出了ABDE

C都挂了。。。

题解:

A

题解:

模拟

判断前面一段是否相同,后面一段是否相同,长度是否够(不能有重叠)

Code:

 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<map>
 7 #include<set>
 8 #include<cmath>
 9 #include<iostream>
10 #include<queue>
11 #include<string>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pii;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 typedef pair<long long,long long> pll;
18 #define fi first
19 #define se second
20 #define pb push_back
21 #define mp make_pair
22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
24
25 ll read(){
26     ll x=0,f=1;char c=getchar();
27     while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
28     while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
29     return x*f;
30 }
31
32 int n,m;
33 string a,b;
34
35 int main(){
36     n=read(),m=read();
37     cin>>a>>b;
38     int pos=-1;
39     for(int i=0;i<n;i++){
40         if(a[i]==‘*‘){
41             pos=i;
42             break;
43         }
44     }
45     if(pos==-1){
46         if(a==b) puts("YES");
47         else puts("NO");
48         return 0;
49     }
50
51     if(n>m+1){
52         puts("NO");
53         return 0;
54     }
55
56     for(int i=0;i<pos;i++){
57         if(a[i]!=b[i]){
58             puts("NO");
59             return 0;
60         }
61     }
62     for(int i=n-1;i>pos;i--){
63         if(a[i]!=b[i-n+m]){
64             puts("NO");
65             return 0;
66         }
67     }
68     puts("YES");
69     return 0;
70 }

B

题解:

简单计算

考虑几种情况:

1. k<=n+1 那么任意一种构造都可行 答案为(k-1)/2

2. k>n+n-1 没有可行解 答案为零

3. 从(k-n)+n到(k/2+k/2) 分k的奇偶性讨论一下

Code:

 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<map>
 7 #include<set>
 8 #include<cmath>
 9 #include<iostream>
10 #include<queue>
11 #include<string>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pii;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 typedef pair<long long,long long> pll;
18 #define fi first
19 #define se second
20 #define pb push_back
21 #define mp make_pair
22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
24
25 ll read(){
26     ll x=0,f=1;char c=getchar();
27     while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
28     while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
29     return x*f;
30 }
31
32 ll n,k;
33
34 int main(){
35     n=read();k=read();
36     ll ans=0;
37     if(k<=n+1) ans=(k-1)/2;
38     else if(k>n+n-1) ans=0;
39     else{
40         ll nw=k/2;
41         ll l=k-n;
42         if(k%2==0) nw--;
43         ans=nw-l+1;
44     }
45     cout<<ans<<endl;
46     return 0;
47 }

C

题解:

模拟

看到(就加进去 直到够了为止

但是如果用string s; s+=‘(‘;

由于string特别慢 于是会超时。。。

所以我们改用数组存储每一位是(还是)

Code:

 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<map>
 7 #include<set>
 8 #include<cmath>
 9 #include<iostream>
10 #include<queue>
11 #include<string>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pii;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 typedef pair<long long,long long> pll;
18 #define fi first
19 #define se second
20 #define pb push_back
21 #define mp make_pair
22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
24
25 ll read(){
26     ll x=0,f=1;char c=getchar();
27     while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
28     while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
29     return x*f;
30 }
31
32 int n,m;
33 string s;
34 string ans;
35 int res[200200],sz;
36
37 int main(){
38     n=read(),m=read();
39     cin>>s;
40     int num=m/2;
41     int nw=0,dif=0;
42     for(int i=0;i<s.size();i++){
43         if(s[i]==‘(‘){
44             nw++;dif++;
45             res[++sz]=1;
46             if(nw==num) break;
47         }
48         else{
49             if(dif){
50                 res[++sz]=2;
51                 dif--;
52             }
53         }
54     }
55     while(dif--) res[++sz]=2;
56     for(int i=1;i<=sz;i++)
57         if(res[i]==1) putchar(‘(‘); else putchar(‘)‘);
58     puts("");
59     return 0;
60 }

D

题解:

首先我们把整个刷上1

然后0的情况就没有了

剩下我们按照题意模拟

每个数我们找到最左的位置和最右的位置

在线段树上更新 把这段区间刷成这个数

注意如果最大的数没有出现 那么我们得加上这个数 因为他是最后刷的 所以可以放在任何为0的位置上

然后如果现在的这个序列和原来的有矛盾(原来某一位和现在不同) 那么就是-1

否则输出这个序列

Code:

  1 #include<stdio.h>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<map>
  7 #include<set>
  8 #include<cmath>
  9 #include<iostream>
 10 #include<queue>
 11 #include<string>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,int> pii;
 15 typedef long double ld;
 16 typedef unsigned long long ull;
 17 typedef pair<long long,long long> pll;
 18 #define fi first
 19 #define se second
 20 #define pb push_back
 21 #define mp make_pair
 22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
 23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
 24
 25 ll read(){
 26     ll x=0,f=1;char c=getchar();
 27     while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
 28     while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
 29     return x*f;
 30 }
 31
 32 const int maxn=200200;
 33 int n,q;
 34 int a[maxn];
 35 int l[maxn],r[maxn];
 36
 37 struct Node{
 38     int l,r,val;
 39     int tag;
 40 } tr[maxn*4];
 41
 42 #define lc (i<<1)
 43 #define rc (i<<1|1)
 44
 45 void build(int i,int l,int r){
 46     tr[i].l=l,tr[i].r=r;
 47     if(l==r)
 48         return;
 49     int md=(l+r)>>1;
 50     build(lc,l,md);
 51     build(rc,md+1,r);
 52 }
 53
 54 void pushdown(int i){
 55     if(!tr[i].tag) return;
 56     tr[lc].tag=tr[rc].tag=tr[lc].val=tr[rc].val=tr[i].tag;
 57     tr[i].tag=0;
 58     return;
 59 }
 60
 61 void upd(int i,int l,int r,int v){
 62     if(tr[i].l>=l && tr[i].r<=r){
 63         tr[i].val=v;
 64         tr[i].tag=v;
 65         return;
 66     }
 67     if(tr[i].l>r || tr[i].r<l) return;
 68     pushdown(i);
 69     upd(lc,l,r,v);upd(rc,l,r,v);
 70 }
 71
 72 int ask(int i,int pos){
 73     if(tr[i].l>pos || tr[i].r<pos) return 0;
 74     if(tr[i].l==tr[i].r) return tr[i].val;
 75     pushdown(i);
 76     return max(ask(lc,pos),ask(rc,pos));
 77 }
 78
 79 int main(){
 80     n=read(),q=read();
 81     bool ok=0;
 82     int mx=0;
 83     rep(i,1,n){
 84         a[i]=read();
 85         if(a[i]==0) ok=1;
 86         mx=max(mx,a[i]);
 87     }
 88     if(!ok){
 89         if(mx!=q){
 90             puts("NO");
 91             return 0;
 92         }
 93     }
 94
 95     if(mx!=q){
 96         rep(i,1,n){
 97             if(a[i]==0){
 98                 a[i]=q;
 99                 break;
100             }
101         }
102     }
103
104     rep(i,1,n){
105         int nw=a[i];
106         if(l[nw]==0) l[nw]=i;
107         r[nw]=max(r[nw],i);
108     }
109
110     build(1,1,n);
111     l[1]=1,r[1]=n;
112     rep(i,1,q)
113         if(l[i]) upd(1,l[i],r[i],i);
114
115     rep(i,1,n){
116         int nw=ask(1,i);
117         if(a[i] && a[i]!=nw){
118             puts("NO");
119             return 0;
120         }
121         a[i]=nw;
122     }
123
124     puts("YES");
125     rep(i,1,n)
126         printf("%d ",a[i]);
127     puts("");
128
129     return 0;
130 }

E

题解:

交互题

很有趣

首先我们可以方便的得出前n-1步

就是每次询问当前格子向右的一个格子能不能到(n,n)

如果能 那么向右走 否则向下走

这样我们可以走到对角线上

然后不能这么询问了

所以我们反过来做

但是因为路径不止一条 我们有可能不能走到同一个对角线上的格子

怎么办呢

我们换一种询问方式

从(n,n)开始

然后每次询问当前格子的上方一个格子能否到达之前哪条路径上与之距离为n-1的那个格子

具体见代码

如果能走 就往上走 否则往左走

为什么是对的呢

因为我们一定会得到所有路径里最靠右的那一条路径

Code:

 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<map>
 7 #include<set>
 8 #include<cmath>
 9 #include<iostream>
10 #include<queue>
11 #include<string>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pii;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 typedef pair<long long,long long> pll;
18 #define fi first
19 #define se second
20 #define pb push_back
21 #define mp make_pair
22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
24
25 ll read(){
26     ll x=0,f=1;char c=getchar();
27     while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
28     while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
29     return x*f;
30 }
31
32 int n;
33 string ans1,ans2;
34
35 bool ask(int a,int b,int c,int d){
36     printf("? %d %d %d %d\n",a,b,c,d);
37     fflush(stdout);
38     string ret;
39     cin>>ret;
40     if(ret=="YES") return 1;
41     else return 0;
42 }
43
44 int main(){
45     n=read();
46     int nwx=1,nwy=1;
47     for(int i=1;i<n;i++){
48         bool nw=ask(nwx,nwy+1,n,n);
49         if(nw) ans1=ans1+‘R‘,nwy++;
50         else ans1=ans1+‘D‘,nwx++;
51     }
52     int xx=n,yy=n;
53     for(int i=n-2;i>=0;i--){
54         if(ans1[i]==‘R‘) nwy--;
55         else nwx--;
56         bool nw=ask(nwx,nwy,xx-1,yy);
57         if(nw) ans2=‘D‘+ans2,xx--;
58         else ans2=‘R‘+ans2,yy--;
59     }
60     cout<<"! "<<ans1<<ans2<<endl;
61     fflush(stdout);
62     return 0;
63 }

F

题解:

好题

首先我们先把那些“我的路径”加进图中

用并查集维护连通性

然后对于每一条新的路径:

如果两端在一个联通块内 那么记录下来

否则加进图中 并且更新并查集

这样我们得到一棵树和一些边

然后dfs一遍整理树的结构 求出每个点的father和depth

下面是精华部分

我们还是用一个并查集维护这棵树

现在我们要做的操作是:对于之前每条未加进图中的边,我们把两端点之间的路径更新成这条边的边权,不能重复更新

因为输入的时候就是排好序的所以不需要重复更新

问题在于每条边如何正好被更新一次

就是说我们在更新后边的时候要跳过一些前边被更新过的边

我们用fa[x]表示这个点在往上跳的时候跳到的点 也就是说从x到fa[x]的路径都被更新过 并且fa[x]到f[fa[x]]这条边没有被更新

那么直接这样跳一跳直到两个端点跳到同一个点就结束了

怎么维护fa呢

我们只需要在往上跳的时候令fa[x]=fp(f[x])就可以了 fp在这里表示的就是找到上一个没有更新的点

Code:

  1 #include<stdio.h>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<map>
  7 #include<set>
  8 #include<cmath>
  9 #include<iostream>
 10 #include<queue>
 11 #include<string>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,int> pii;
 15 typedef long double ld;
 16 typedef unsigned long long ull;
 17 typedef pair<long long,long long> pll;
 18 #define fi first
 19 #define se second
 20 #define pb push_back
 21 #define mp make_pair
 22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
 23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
 24
 25 ll read(){
 26     ll x=0,f=1;char c=getchar();
 27     while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
 28     while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
 29     return x*f;
 30 }
 31
 32 const int maxn=500500;
 33
 34 int n,m,k,num;
 35 int fa[maxn];
 36
 37 struct Edge{
 38     int fr,to,len,tp;
 39 };
 40 vector<Edge> edges;
 41 vector<int> gr[maxn];
 42
 43 inline int fp(int x){if(fa[x]==x) return x;return fa[x]=fp(fa[x]);}
 44 inline void uni(int a,int b){a=fp(a),b=fp(b);if(a!=b) fa[a]=b;}
 45
 46 void add_edge(int a,int b,int l,int t){
 47     edges.pb((Edge){a,b,l,t});
 48     edges.pb((Edge){b,a,l,t});
 49     num=edges.size();
 50     gr[a].pb(num-2);
 51     gr[b].pb(num-1);
 52 }
 53
 54 int A[maxn],B[maxn],L[maxn],cnt;
 55 int f[maxn],d[maxn],res[maxn];
 56
 57 void dfs(int x,int pa=1){
 58     f[x]=pa;
 59     for(int i=0;i<gr[x].size();i++){
 60         int ind=gr[x][i];
 61         Edge nw=edges[ind];
 62         if(nw.to==f[x]) continue;
 63         d[nw.to]=d[x]+1;
 64         dfs(nw.to,x);
 65     }
 66 }
 67
 68 int ans[maxn];
 69
 70 int main(){
 71 //    freopen("in","r",stdin);
 72     n=read(),k=read(),m=read();
 73     rep(i,1,n) fa[i]=i;
 74     for(int i=1;i<=k;i++){
 75         int a=read(),b=read();
 76         add_edge(a,b,0,0);
 77         uni(a,b);
 78     }
 79     for(int i=1;i<=m;i++){
 80         int x=read(),y=read(),l=read();
 81         int fx=fp(x),fy=fp(y);
 82         if(fx!=fy){fa[fx]=fy;add_edge(x,y,l,1);}
 83         else{A[++cnt]=x,B[cnt]=y,L[cnt]=l;}
 84     }
 85
 86     d[1]=1;
 87     dfs(1);
 88
 89     for(int i=1;i<=n;i++)
 90         fa[i]=i;
 91
 92     for(int i=1;i<=cnt;i++){
 93         int nwx=A[i],nwy=B[i],nwl=L[i];
 94         nwx=fp(nwx),nwy=fp(nwy);
 95         while(nwx!=nwy){
 96             if(d[nwx]>=d[nwy]){
 97                 res[nwx]=nwl;
 98                 fa[nwx]=fp(f[nwx]);
 99                 nwx=fa[nwx];
100             }
101             else{
102                 res[nwy]=nwl;
103                 fa[nwy]=fp(f[nwy]);
104                 nwy=fa[nwy];
105             }
106         }
107     }
108
109     //for(int i=1;i<=n;i++) cout<<res[i]<<endl;
110
111     ll ans=0;
112     for(int i=1;i<=n;i++){
113         for(int j=0;j<gr[i].size();j++){
114             int ind=gr[i][j];
115             Edge nw=edges[ind];
116             if(nw.to==f[i] && nw.tp==0){
117                 if(fa[i]==i){
118                     puts("-1");
119                     return 0;
120                 }
121                 ans+=res[i];
122             }
123         }
124     }
125     cout<<ans<<endl;
126     return 0;
127 }
128     

总结

1. 字符串string类很慢 尽量不要用string加string的操作

2. 想好了再写 不要出现细节错误

原文地址:https://www.cnblogs.com/wawawa8/p/9496391.html

时间: 2024-08-30 05:50:30

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)的相关文章

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching B. Pair of Toys C. Bracket Subsequence D. Array Restoration-区间查询最值(RMQ(ST))

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching 题意就是匹配字符的题目,打比赛的时候没有看到只有一个" * ",然后就写挫了,被hack了,被hack的点就是判一下只有一个" * ". 1 //A 2 #include<iostream> 3 #include<cstdio&g

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) D. Array Restoration

D. Array Restoration time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Initially there was an array aa consisting of nn integers. Positions in it are numbered from 11 to nn. Exactly qq querie

Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) -B C(GCD,最长连续交替序列)

B. Weakened Common Divisor time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output During the research on properties of the greatest common divisor (GCD) of a set of numbers, Ildar, a famous mat

Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)

A : A. Doggo Recoloring time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Panic is rising in the committee for doggo standardization — the puppies of the new brood have been born multi-colore

【Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) B】Weakened Common Divisor

[链接] 我是链接,点我呀:) [题意] 给你n个数对(ai,bi). 让你求一个大于1的数字x 使得对于任意的i x|a[i] 或者 x|b[i] [题解] 求出第一个数对的两个数他们有哪些质因子. 显然用这些质因子去试2..n就可以了. 看哪个可以满足 就输出对应的就可以了. (一开始我求出这个数的所有因子(TLE了)..其实没有必要...因为假设y是x的倍数..然后y满足的话,显然x也能满足要求..所以只要用质因子搞就行了. [代码] #include <bits/stdc++.h> #

Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) 题解

真心简单的一场比赛 就是坑比较多(自己太蠢) A是一个水题 3分钟的时候过了 B也是一个比较简单的题 类似的套路见得多了 但是我当时可能比较困 想了一会才想出来 19分钟的时候过掉了 C同样很显然 性质不难发现 我在30分钟的时候通过了pretest 但是由于自己的愚蠢 忘记写了一句话 导致FST了... D本来是一个简单的dp题 但是我一直没往dp上想 在网络流上刚了1h之后终于换了思路 在1:45的时候通过了他 然后就时间不多了 E都没看 就去hack 成功hack了2个之后比赛就结束了 题

codeforces cf round#505(based on vk cup 2018 final) C. Plasticine zebra

构造题,把整个串想象成一个环.每次把环断开并反转的时候从切口处看进去的顺序是和刚开始从头到尾的顺序是一样的.于是每次不管如何翻转最后都要找到这个环上最大的连续子段长度 #include<bits/stdc++.h> using namespace std; string s; int main() { cin>>s; int tmp=s.size(); s=s+s; int ans=0; int len=1; for(int i=0;i<(int)s.size()-1;i++

Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)C. Producing Snow+差分标记

题目链接:C. Producing Snow 题意:给两个数组v[N],T[N],v[i]表示第i天造的雪,T[i],表示第i天的温度,一堆雪如果<=T[i],当天就会融完,否则融化T[i],要求输出每天的融雪总量. 题解:我对T数组求个前缀和,就可以二分找到每堆雪在那一天(pos)融化,余下的要加进答案中ans[i],然后用一个an数组在a[i]+1,a[pos]-1,最后求再求一次前缀和. ans[i]再加上an[i]*t[i].每次操作二分logn,N次操作.复杂度O(nlogn) #in

Codeforces Round #472 (rated, Div. 2, based on VK Cup 2018 Round 2)

A. Tritonic Iridescence 题解:分类讨论.注意题目要求,至少有两种方案. 1 #pragma warning(disable:4996) 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 int n, m; 10 stri