考场上只做出了ABDE

C都挂了。。。

题解:

A

题解:

模拟

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

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,m;
string a,b; int main(){
n=read(),m=read();
cin>>a>>b;
int pos=-;
for(int i=;i<n;i++){
if(a[i]=='*'){
pos=i;
break;
}
}
if(pos==-){
if(a==b) puts("YES");
else puts("NO");
return ;
} if(n>m+){
puts("NO");
return ;
} for(int i=;i<pos;i++){
if(a[i]!=b[i]){
puts("NO");
return ;
}
}
for(int i=n-;i>pos;i--){
if(a[i]!=b[i-n+m]){
puts("NO");
return ;
}
}
puts("YES");
return ;
}

B

题解:

简单计算

考虑几种情况:

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

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

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

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} ll n,k; int main(){
n=read();k=read();
ll ans=;
if(k<=n+) ans=(k-)/;
else if(k>n+n-) ans=;
else{
ll nw=k/;
ll l=k-n;
if(k%==) nw--;
ans=nw-l+;
}
cout<<ans<<endl;
return ;
}

C

题解:

模拟

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

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

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

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

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,m;
string s;
string ans;
int res[],sz; int main(){
n=read(),m=read();
cin>>s;
int num=m/;
int nw=,dif=;
for(int i=;i<s.size();i++){
if(s[i]=='('){
nw++;dif++;
res[++sz]=;
if(nw==num) break;
}
else{
if(dif){
res[++sz]=;
dif--;
}
}
}
while(dif--) res[++sz]=;
for(int i=;i<=sz;i++)
if(res[i]==) putchar('('); else putchar(')');
puts("");
return ;
}

D

题解:

首先我们把整个刷上1

然后0的情况就没有了

剩下我们按照题意模拟

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

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

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

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

否则输出这个序列

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} const int maxn=;
int n,q;
int a[maxn];
int l[maxn],r[maxn]; struct Node{
int l,r,val;
int tag;
} tr[maxn*]; #define lc (i<<1)
#define rc (i<<1|1) void build(int i,int l,int r){
tr[i].l=l,tr[i].r=r;
if(l==r)
return;
int md=(l+r)>>;
build(lc,l,md);
build(rc,md+,r);
} void pushdown(int i){
if(!tr[i].tag) return;
tr[lc].tag=tr[rc].tag=tr[lc].val=tr[rc].val=tr[i].tag;
tr[i].tag=;
return;
} void upd(int i,int l,int r,int v){
if(tr[i].l>=l && tr[i].r<=r){
tr[i].val=v;
tr[i].tag=v;
return;
}
if(tr[i].l>r || tr[i].r<l) return;
pushdown(i);
upd(lc,l,r,v);upd(rc,l,r,v);
} int ask(int i,int pos){
if(tr[i].l>pos || tr[i].r<pos) return ;
if(tr[i].l==tr[i].r) return tr[i].val;
pushdown(i);
return max(ask(lc,pos),ask(rc,pos));
} int main(){
n=read(),q=read();
bool ok=;
int mx=;
rep(i,,n){
a[i]=read();
if(a[i]==) ok=;
mx=max(mx,a[i]);
}
if(!ok){
if(mx!=q){
puts("NO");
return ;
}
} if(mx!=q){
rep(i,,n){
if(a[i]==){
a[i]=q;
break;
}
}
} rep(i,,n){
int nw=a[i];
if(l[nw]==) l[nw]=i;
r[nw]=max(r[nw],i);
} build(,,n);
l[]=,r[]=n;
rep(i,,q)
if(l[i]) upd(,l[i],r[i],i); rep(i,,n){
int nw=ask(,i);
if(a[i] && a[i]!=nw){
puts("NO");
return ;
}
a[i]=nw;
} puts("YES");
rep(i,,n)
printf("%d ",a[i]);
puts(""); return ;
}

E

题解:

交互题

很有趣

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

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

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

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

然后不能这么询问了

所以我们反过来做

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

怎么办呢

我们换一种询问方式

从(n,n)开始

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

具体见代码

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

为什么是对的呢

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

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n;
string ans1,ans2; bool ask(int a,int b,int c,int d){
printf("? %d %d %d %d\n",a,b,c,d);
fflush(stdout);
string ret;
cin>>ret;
if(ret=="YES") return ;
else return ;
} int main(){
n=read();
int nwx=,nwy=;
for(int i=;i<n;i++){
bool nw=ask(nwx,nwy+,n,n);
if(nw) ans1=ans1+'R',nwy++;
else ans1=ans1+'D',nwx++;
}
int xx=n,yy=n;
for(int i=n-;i>=;i--){
if(ans1[i]=='R') nwy--;
else nwx--;
bool nw=ask(nwx,nwy,xx-,yy);
if(nw) ans2='D'+ans2,xx--;
else ans2='R'+ans2,yy--;
}
cout<<"! "<<ans1<<ans2<<endl;
fflush(stdout);
return ;
}

F

题解:

好题

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

用并查集维护连通性

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

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

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

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

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

下面是精华部分

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

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

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

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

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

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

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

怎么维护fa呢

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

Code:

 #include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k) for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--) ll read(){
ll x=,f=;char c=getchar();
while(c<'' || c>''){if(c=='-')f=-;c=getchar();}
while(c>='' && c<=''){x=x*+c-'';c=getchar();}
return x*f;
} const int maxn=; int n,m,k,num;
int fa[maxn]; struct Edge{
int fr,to,len,tp;
};
vector<Edge> edges;
vector<int> gr[maxn]; inline int fp(int x){if(fa[x]==x) return x;return fa[x]=fp(fa[x]);}
inline void uni(int a,int b){a=fp(a),b=fp(b);if(a!=b) fa[a]=b;} void add_edge(int a,int b,int l,int t){
edges.pb((Edge){a,b,l,t});
edges.pb((Edge){b,a,l,t});
num=edges.size();
gr[a].pb(num-);
gr[b].pb(num-);
} int A[maxn],B[maxn],L[maxn],cnt;
int f[maxn],d[maxn],res[maxn]; void dfs(int x,int pa=){
f[x]=pa;
for(int i=;i<gr[x].size();i++){
int ind=gr[x][i];
Edge nw=edges[ind];
if(nw.to==f[x]) continue;
d[nw.to]=d[x]+;
dfs(nw.to,x);
}
} int ans[maxn]; int main(){
// freopen("in","r",stdin);
n=read(),k=read(),m=read();
rep(i,,n) fa[i]=i;
for(int i=;i<=k;i++){
int a=read(),b=read();
add_edge(a,b,,);
uni(a,b);
}
for(int i=;i<=m;i++){
int x=read(),y=read(),l=read();
int fx=fp(x),fy=fp(y);
if(fx!=fy){fa[fx]=fy;add_edge(x,y,l,);}
else{A[++cnt]=x,B[cnt]=y,L[cnt]=l;}
} d[]=;
dfs(); for(int i=;i<=n;i++)
fa[i]=i; for(int i=;i<=cnt;i++){
int nwx=A[i],nwy=B[i],nwl=L[i];
nwx=fp(nwx),nwy=fp(nwy);
while(nwx!=nwy){
if(d[nwx]>=d[nwy]){
res[nwx]=nwl;
fa[nwx]=fp(f[nwx]);
nwx=fa[nwx];
}
else{
res[nwy]=nwl;
fa[nwy]=fp(f[nwy]);
nwy=fa[nwy];
}
}
} //for(int i=1;i<=n;i++) cout<<res[i]<<endl; ll ans=;
for(int i=;i<=n;i++){
for(int j=;j<gr[i].size();j++){
int ind=gr[i][j];
Edge nw=edges[ind];
if(nw.to==f[i] && nw.tp==){
if(fa[i]==i){
puts("-1");
return ;
}
ans+=res[i];
}
}
}
cout<<ans<<endl;
return ;
}

总结

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

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

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

  1. E - Down or Right Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)

    http://codeforces.com/contest/1023/problem/E 交互题 #include <cstdio> #include <cstdlib> #i ...

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

    我们知道不满足的肯定是两边大中间小的,这样就用RMQ查询两个相同等值的区间内部最小值即可,注意边界条件 #include<bits/stdc++.h> #define x first #d ...

  3. Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-C-Bracket Subsequence

    #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> ...

  4. Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-A-Single Wildcard Pattern Matching

    #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> ...

  5. Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) E. Down or Right

    从(1,1,n,n)每次只变一个坐标,进行询问. 如果问到对角线有距离限制, 再从(1,1,n/2,n/2)询问到(n/2,n/2,n,n) 记住前半部分贪心忘上走,后本部分贪心往右走 因为最后的路线 ...

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

    http://codeforces.com/contest/1025/problem/D 树 dp 优化 f[x][y][0]=f[x][z][1] & f[z+1][y][0] ( gcd( ...

  7. 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 ...

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

    题目链接 让你找一个数,使得这个数,可以被每个二元组的两个数中的一个数整除. 先将第一个二元组的两个数质因数分解一下,分解的质数加入set中,然后,对剩下的n-1个二元组进行遍历,每次遍历到的二元组对 ...

  9. 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 stand ...

随机推荐

  1. Storm项目:流数据监控1《设计文档…

    博客公告: (1)本博客全部博客文章搬迁至<博客虫>http://blogchong.com/ (2)文章相应的源代码下载链接參考博客虫站点首页的"代码GIT". (3 ...

  2. iframe引入页面

    将外层css框架单独存放在一个css文件之中,将iframe的css单独写在一个css文件,避免iframe中的html,body等公共部分的样式冲突. 外层框架单独写在一个css,如: frame. ...

  3. Could not load file or assembly 'MyAssembly.XmlSerializers

    https://stackoverflow.com/questions/17755559/could-not-load-file-or-assembly-myassembly-xmlserialize ...

  4. javascript 树形菜单

    1. [代码][JavaScript]代码     var ME={ini:{i:true,d:{},d1:{},h:0,h1:0,h2:0},html:function(da,f){var s='& ...

  5. fuse的mount机制-流程及参数

    在bbfs中,传递的参数有两个目录,fuse将一个目录挂载在另一个目录下. 在ssfs中,传递的参数只有一个目录(传递两个目录fuse会出错). 问题:那么fuse的mount机制到底需要几个目录参数 ...

  6. CodeForces-607B:Zuma (基础区间DP)

    Genos recently installed the game Zuma on his phone. In Zuma there exists a line of n gemstones, the ...

  7. linux学习二(小随笔)

    1apt-get 解包命令 tar zxvf ......... 打包命令 tar czvf ......... gz gunzip ........gz gzip    ..........gz l ...

  8. Java常用数据结构和算法

    二叉树: 1.每个结点不能多于两个子树: 2.一颗平衡二叉树的深度要比及结点个数N小得多. 二叉查找树: 1.结点x的所有左子树的值小于x,所有右子树的值大于x: AVL树: 1.一种带有平衡条件的二 ...

  9. 【转】IntelliJ IDEA搭建Spring环境

    //本来在草稿箱写好了,忘记发就被冲掉了,重新再写一遍. Spring初探 Spring初探 在IntelliJ IDEA中创建Spring项目 一个简单的例子介绍框架的作用 那么什么时候new的对象 ...

  10. Windows下如何生成数字证书

    1.Makecert.exe<证书创建工具>使用说明:http://msdn.microsoft.com/zh-cn/library/bfsktky3.aspx 2.SignTool.ex ...