Lyft Level 5 Challenge 2018 - Final Round Div. 1没翻车记
夜晚使人着迷。没有猝死非常感动。
A:显然对于水平线段,只有横坐标的左端点为1的时候才可能对答案产生影响;对于竖直直线,如果要删一定是删去一段前缀。枚举竖直直线删到哪一条,记一下需要删几条水平线段就可以了。想当然的以为竖直直线横坐标是升序排的,因为这个wa了两发感觉非常惨。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,line[N],row[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read();
for (int i=;i<=n;i++) line[i]=read();line[++n]=;sort(line+,line+n+);
int t=;
for (int i=;i<=m;i++)
{
int x=read(),y=read();read();
if (x==) row[++t]=y+;
}
sort(row+,row+t+);
int x=,cnt=t,ans=n+m;
for (int i=;i<=n;i++)
{
while (x<t&&row[x+]<=line[i]) x++,cnt--;
ans=min(ans,cnt+i-);
}
cout<<ans;
return ;
}
B:注意到五次实在是太少了连log都不到,那么看起来一定可以更少。只需要两次询问。第一次在第二个人给出的点中随便选一个,询问该点在第一个人那里的编号。如果该编号在第一个人给出的点中出现,直接输出就可以了;否则注意到树上的点到另一连通块的路径是唯一的,我们只需要从该点沿着树爬,直到第一次进入该连通块,记录所遇到的第一个连通块内的点。那么如果两个连通块有交点,该点一定同时在两个连通块内。所以只要问一下这个点在第二个人那里的编号就可以了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 1010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,p[N],k1,k2,a[N],b[N],flag[N],flag2[N],t;
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
int dfs(int x,int from)
{
if (flag[x]) return x;
for (int i=p[x];i;i=edge[i].nxt)
if (edge[i].to!=from)
{
int y=dfs(edge[i].to,x);
if (y) return y;
}
return ;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
T=read();
while (T--)
{
n=read();memset(p,,sizeof(p));t=;
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}memset(flag,,sizeof(flag));memset(flag2,,sizeof(flag2));
k1=read();
for (int i=;i<=k1;i++) flag[read()]=;
k2=read();
for (int i=;i<=k2;i++) b[i]=read(),flag2[b[i]]=;
cout<<'B'<<' '<<b[]<<endl;
int x=read();
if (flag[x]) cout<<'C'<<' '<<x<<endl;
else
{
int y=dfs(x,x);
cout<<'A'<<' '<<y<<endl;
int p=read();
if (flag2[p]) cout<<'C'<<' '<<y<<endl;
else cout<<'C'<<' '<<-<<endl;
}
}
return ;
}
这个时候花掉了50min,处于A两题的最后一名,感觉掉rating非常稳了。C看上去非常可怕,看了看榜发现不少人莫名其妙的只过了D,于是赶紧去看。诶这个东西我是不是见过啊?https://www.cnblogs.com/Gloid/p/9723734.html 于是非常开心了感觉能翻啊。
D:每次获得的信息可以看做是两个前缀和的异或。如果要知道某段区间的异或值也即该两个前缀和的异或值,这两个前缀必须通过已给的信息连通。LCT维护一发路径异或值就可以了。事实上cf好像很少有高级数据结构题,所以其实带权并查集就可以维护了,感觉自己是弱智。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
#define N 200010
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
#define lself tree[tree[k].fa].ch[0]
#define rself tree[tree[k].fa].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
map<int,int> id;
int q,lastans,cnt;
struct data{int x,fa,ch[],rev,sum;
}tree[N*];
void up(int k){tree[k].sum=tree[lson].sum^tree[rson].sum^tree[k].x;}
void rev(int k){if (k) swap(lson,rson),tree[k].rev^=;}
void down(int k){if (tree[k].rev) rev(lson),rev(rson),tree[k].rev=;}
bool isroot(int k){return lself!=k&&rself!=k;}
void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);}
int whichson(int k){return rself==k;}
void move(int k,int p)
{
int fa=tree[k].fa,gf=tree[fa].fa;
if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
tree[fa].ch[p]=tree[k].ch[!p],tree[tree[fa].ch[p]].fa=fa;
tree[k].ch[!p]=fa,tree[fa].fa=k;
up(fa),up(k);
}
void splay(int k)
{
push(k);
while (!isroot(k))
{
int fa=tree[k].fa;
if (!isroot(fa))
if (whichson(k)^whichson(fa)) move(k,whichson(k));
else move(fa,whichson(k));
move(k,whichson(k));
}
}
void access(int k){for (int t=;k;t=k,k=tree[k].fa) splay(k),tree[k].ch[]=t,up(k);}
int findroot(int k){access(k),splay(k);for (;lson;k=lson) down(k);splay(k);return k;}
void makeroot(int k){access(k),splay(k),rev(k);}
int query(int x,int y){makeroot(x),access(y),splay(y);return tree[y].sum;}
void link(int x,int y)
{
if (findroot(x)!=findroot(y))
makeroot(x),tree[x].fa=y;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
#endif
q=read();
while (q--)
{
int op=read();
if (op==)
{
int l=read()^lastans,r=read()^lastans,x=read()^lastans;
if (l>r) swap(l,r);
if (!id[l-]) id[l-]=++cnt;
if (!id[r]) id[r]=++cnt;
int p=id[l-],q=id[r];
if (findroot(p)==findroot(q)) ;
else cnt++,tree[cnt].x=x,link(cnt,p),link(cnt,q);
}
else
{
int l=read()^lastans,r=read()^lastans;
if (l>r) swap(l,r);
int p=id[l-],q=id[r];
if (!p||!q||findroot(p)!=findroot(q)) lastans=-;
else lastans=query(p,q);
printf("%d\n",lastans);
if (lastans==-) lastans=;
}
}
return ;
}
然后滚去看C。没什么思路于是度娘一发看有没有什么启发性的东西,突然就找到一个类似曼哈顿距离之和就是矩形周长。诶那k>=4就做完了啊?然后冷静了好长时间去想k=3最后总算还是搞出来了。
C:首先注意到所要求的曼哈顿距离之和就是所选出的点的值域所构成的矩形的周长。那么对于k>=4,横坐标min、横坐标max、纵坐标min、纵坐标max就一定可以取到了。对于k=3,由抽屉原理,有两个点是只提供矩形的一个边界的,那么他们一定在取到极值时最优。所以暴力枚举提供至少两个边界的点,再枚举一下剩下的两个点提供的是哪项边界就可以了。写的时候写丑了或者说当时不是这么想的。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,ans,sufmax[N],sufmin[N];
struct data{int x,y;
}a[N];
bool cmp(const data&a,const data&b)
{
return a.x<b.x;
}
bool cmp2(const data&a,const data&b)
{
return a.y<b.y;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=;i<=n;i++) a[i].x=read(),a[i].y=read();
int l=a[].x,r=a[].x,u=a[].y,d=a[].y;
for (int i=;i<=n;i++)
{
l=min(l,a[i].x);
r=max(r,a[i].x);
u=max(u,a[i].y);
d=min(d,a[i].y);
}
ans=(r-l+u-d)*;
int ans2=;
sort(a+,a+n+,cmp);
sufmax[n]=a[n].y,sufmin[n]=a[n].y;
for (int i=n-;i>=;i--) sufmax[i]=max(sufmax[i+],a[i].y),sufmin[i]=min(sufmin[i+],a[i].y);
for (int i=;i<n;i++) ans2=max(ans2,(a[n].x-a[i].x+max(sufmax[i]-min(a[i].y,a[n].y),max(a[i].y,a[n].y)-sufmin[i]))<<);
for (int i=;i<=n;i++) swap(a[i].x,a[i].y);
sort(a+,a+n+,cmp);
sufmax[n]=a[n].y,sufmin[n]=a[n].y;
for (int i=n-;i>=;i--) sufmax[i]=max(sufmax[i+],a[i].y),sufmin[i]=min(sufmin[i+],a[i].y);
for (int i=;i<n;i++) ans2=max(ans2,(a[n].x-a[i].x+max(sufmax[i]-min(a[i].y,a[n].y),max(a[i].y,a[n].y)-sufmin[i]))<<);
for (int i=;i<=n;i++) a[i].x=-a[i].x;
sort(a+,a+n+,cmp);
sufmax[n]=a[n].y,sufmin[n]=a[n].y;
for (int i=n-;i>=;i--) sufmax[i]=max(sufmax[i+],a[i].y),sufmin[i]=min(sufmin[i+],a[i].y);
for (int i=;i<n;i++) ans2=max(ans2,(a[n].x-a[i].x+max(sufmax[i]-min(a[i].y,a[n].y),max(a[i].y,a[n].y)-sufmin[i]))<<);
for (int i=;i<=n;i++) a[i].x=-a[i].x;
for (int i=;i<=n;i++) swap(a[i].x,a[i].y);
for (int i=;i<=n;i++) a[i].x=-a[i].x;
sort(a+,a+n+,cmp);
sufmax[n]=a[n].y,sufmin[n]=a[n].y;
for (int i=n-;i>=;i--) sufmax[i]=max(sufmax[i+],a[i].y),sufmin[i]=min(sufmin[i+],a[i].y);
for (int i=;i<n;i++) ans2=max(ans2,(a[n].x-a[i].x+max(sufmax[i]-min(a[i].y,a[n].y),max(a[i].y,a[n].y)-sufmin[i]))<<);
cout<<ans2<<' ';
for (int i=;i<=n;i++) printf("%d ",ans);
return ;
}
历史总是惊人的相似?

但是感觉并不能在这个分数稳住啊。
result:rank 69 rating +70
Lyft Level 5 Challenge 2018 - Final Round Div. 1没翻车记的更多相关文章
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)
这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) B 1075B (思维)
B. Taxi drivers and Lyft time limit per test 1 second memory limit per test 256 megabytes input stan ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2)---ABC
A---The King's Race http://codeforces.com/contest/1075/problem/A 题意: 一个人在\((1,1)\), 一个人在\((n,n)\), 现 ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2)
A. The King's Race 签. #include <bits/stdc++.h> using namespace std; #define ll long long ll n, ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) A. The King's Race
http://codeforces.com/contest/1075/problem/A On a chessboard with a width of nn and a height of nn, ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) C. The Tower is Going Home(思维+双指针)
https://codeforces.com/contest/1075/problem/C 题意 一个宽为1e9*1e9的矩阵中的左下角,放置一个车(车可以移动到同一行或同一列),放置一些墙,竖的占据 ...
- [Lyft Level 5 Challenge 2018 - Elimination Round][Codeforces 1033D. Divisors]
题目链接:1033D - Divisors 题目大意:给定\(n\)个数\(a_i\),每个数的约数个数为3到5个,求\(\prod_{i=1}^{n}a_i\)的约数个数.其中\(1 \leq n ...
- Lyft Level 5 Challenge 2018 - Elimination Round
A. King Escape 签. #include <bits/stdc++.h> using namespace std; ], y[]; int f1(int X, int Y) { ...
- Lyft Level 5 Challenge 2018 - Elimination Round翻车记
打猝死场感觉非常作死. A:判一下起点和终点是否在其两侧即可. #include<iostream> #include<cstdio> #include<cmath> ...
随机推荐
- win10家庭版升级为win10专业版
windows10 升级钥匙: DR9VN-GF3CR-RCWT2-H7TR8-82QGT 亲测可用
- 【shell脚本学习-2】
#!/bin/bash - #echo do you have exetuate this project \n printf "please input your passwd" ...
- PHP中有关IPV4 和IPV6地址转换以及其它一些常见问题
这里主要介绍一下 IPV4 / IPV6 在 PHP / MySQL 中如何转换.以及中间容易碰到的一些问题. 首先介绍两个函数: ip2long:将 IPV4 的字符串互联网协议转换成长整型数字 i ...
- MySQL数据库操作(DDL)
一.创建数据库 语法:create database 数据库名称 [库选项]; 库选项:(可选)数据库的属性,一般有字符集与校对集,保存在数据库所属文件夹下的opt文件 charset:字符集,表示该 ...
- 一个简易的android浏览器。求指教!
开发android的浏览器很简单吧,不过这浏览器倒是很简易.下面每一处代码都备注上注解了!废话不多说,下面直接上代码! 运行后界面 主界面的代码 activity_main.xml布局 <L ...
- hive-show-partitions
展示分区命令 show partitions show partitions 可以展示这个表格之下的所有分区信息.这个命令常常用在使用SQL语句操作数据之前.举个简单的例子,如果我们想要根据uid融合 ...
- 网站标题被篡改成北京赛车、PK10的解决处理办法
客户网站于近日被跳转到赌博网站,打开后直接跳转到什么北京赛车,PK10等内容的网站上去,客户网站本身做了百度的推广,导致所有访问用户都跳转到赌博网站上去,给客户带来很大的经济损失,再一个官方网站的形象 ...
- 【struts2】struts2的使用
1.使用步骤 1) 导入struts2的支持jar包 名称 说明 struts2-core-2.3.4.1.jar Structs2的核心类库 xwork-core-2.3.4.1.jar xwork ...
- (数据科学学习手札08)系统聚类法的Python源码实现(与Python,R自带方法进行比较)
聚类分析是数据挖掘方法中应用非常广泛的一项,而聚类分析根据其大体方法的不同又分为系统聚类和快速聚类,其中系统聚类的优点是可以很直观的得到聚类数不同时具体类中包括了哪些样本,而Python和R中都有直接 ...
- java web项目使用ant编译将不同的功能代码打包成jar,进而分局点将项目打包成不同的tar.gz包进而部署
使用ant可以轻松的将一个项目分离代码,直接打包成不同需求的tar.gz包使用 1.build.properties (属性) version.num=1.0 #版本信息 2.build.xml (a ...