Educational Codeforces Round 58 (Rated for Div. 2) 

题目总链接:https://codeforces.com/contest/1101

A. Minimum Integer

题意:

多组数据,给你三个数l,r,d,要求在区间[l,r]之外找一个最小的x,使得x%d==0。

题解:

当d<l or d>r的时候,直接输出d就好了。

当l<=d<=r的时候,找到最小的t,使得t*d>r就行了。

具体操作见代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int q;
ll l,r,d; int main(){
cin>>q;
while(q--){
cin>>l>>r>>d;
if(d<l || d>r) cout<<d<<endl;
else{
ll now = r/d;
cout<<(now+)*d<<endl;
}
}
return ;
}

B. Accordion

题意:

给出一个字符串,要求删去一些数后它由以下几个部分组成,[ : .... : ],这其中"...."指的是0个或多个“ | ”。

问满足上面条件时,留下的字符串的最大长度为多少。

题解:

模拟一下就好了,从左往右遍历找 [ 以及 :

然后再从右往左遍历找 ] 以及 :

最后找中间的 |

这只是大体思路,代码还需要判断这些是否存在(我就是没判断这个被hack了...)、是否满足条件。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+;
char s[N];
int main(){
scanf("%s",s);
int len = strlen(s);
int j=len,ans=;
for(int i=;i<len;i++){
if(j==len){
if(s[i]=='[') ans++,j--;
continue ;
}else if(j==len-){
if(s[i]==':'){
ans++;
j=i;
break ;
}
}
}
int k=;
for(int i=len-;i>=;i--){
if(k==){
if(s[i]==']') ans++,k++;
continue ;
}else if(k==){
if(s[i]==':'){
ans++;
k=i;
break ;
}
}
}
if(j>=k) puts("-1");
else{
for(int i=j+;i<k;i++){
if(s[i]=='|') ans++;
}
cout<<ans<<endl;
}
return ;
}

C. Division and Union

题意:

给出n个区间,然后将这些区间分到两个集合S1,S2中,要求S1与S2的交集为空。最后输出区间是属于1集合还是2集合。

题解:

一开始想歪了,用并查集去做,虽然也可以做,但是有点麻烦了。

分析一下就可以发现,相交的区间肯定放在一个集合中,不相交的区间可以放在一个集合中,也可以放在另外一个集合中。

那么我们直接按左端点排序后,贪心地将前n-1个区间放在一个集合中,判断第n个区间放入另一个集合是否满足条件就ok了。

注意的是放入一个集合的时候,需要维护右端点的最大值,这样最后比较的时候才能保证正确性。

代码如下:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 2e5+;
int n;
struct Seg{
int l,r,id;
bool operator < (const Seg &A)const{
return l<A.l;
}
}seg[N];
int T;
int ans[N],a[N];
int main(){
cin>>T;
while(T--){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d%d",&seg[i].l,&seg[i].r);
seg[i].id=i;
a[i]=;
}
sort(seg+,seg+n+);
int t=;
int max_r = ;
a[]=;
for(int i=;i<n;i++){
max_r = max(max_r,seg[i].r);
if(!a[i]) a[i]=a[i-];
if(max_r<seg[i+].l){
t++;
a[i+]=t;
}
}
if(!a[n]) a[n]=a[n-];
if(t<) puts("-1");
else{
for(int i=;i<=n;i++){
if(a[i]<t) ans[seg[i].id]=;
else ans[seg[i].id]=;
}
for(int i=;i<=n;i++) printf("%d ",ans[i]);
printf("\n");
}
}
return ;
}

D. GCD Counting

题意:

给出一颗树,每个结点有相应的权值,现在定义g(x,y)为树上x到y的简单路径的所有结点权值的最大公约数,dis(x,y)为x到y路径上面点的个数。求最大的dis(x,y)且满足g(x,y)>1。

题解:

说说比较朴素的方法吧...虽然速度比较慢,但对于我这种蒟蒻比较好懂...

对于2到2e5中的每个数,找出以其为因子的所有点,这些点不一定是连通的,最终呈现出来的应该是多个连通块。

然后我们直接对每个点跑最大直径就行了。

这个算法的具体时间复杂度我也不太清楚,但应该比较高,有方法可以将算法优化到nlogn的级别...

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+;
int a[N],vis[N];
int ans,n;
vector <int> g[N],vec[N];
int dfs(int u){
vis[u]=;
int mx = ;
for(int v:g[u]){
if(vis[v]){
int now = dfs(v);
ans = max(ans,now++mx);
mx = max(mx,now);
}
}
ans=max(ans,);
return mx+;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
for(int j=;j*j<=a[i];j++){
if(a[i]%j) continue ;
vec[j].push_back(i);
if(j*j!=a[i]) vec[a[i]/j].push_back(i);
}
}
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=;i<=2e5;i++){
for(int v:vec[i]) vis[v]=;
for(int u:vec[i]) if(vis[u]) dfs(u);
}
printf("%d",ans);
return ;
}

E. Polycarp's New Job

题意:

在线给出一些矩形的长和宽,以及在线询问:给出一个矩形的箱子,问能否将之前所有给出的矩形装进去。

题解:

这是E题的难度么...感觉比C题还简单点。

对于给出的长和宽,让短边在前,长边在后。然后维护最长短边以及最长长边就行了。因为我们放的时候的最优选择肯定是短边放短边的。

最后询问的时候判断下就ok了...

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+;
int n;
int main(){
cin>>n;
int l = ,r = ;
getchar();
while(n--){
char c;
int x,y;
scanf("%c %d %d",&c,&x,&y);
if(x>y) swap(x,y);
if(c=='+'){
l=max(l,x);
r=max(r,y);
}else{
if(x<l || y<r) puts("NO");
else puts("YES");
}
getchar();
} return ;
}

G. (Zero XOR Subset)-less

题意:

给出n个数,要求尽量多地将这些数划分为连续地几段,并且满足任意子集地异或和不为0。

题解:

只要所有数的异或和都不为0,那么就必然存在一种划分方法,通过这个可以判断可行性。

根据异或的性质,考虑异或前缀和,那么任意一段数的异或和都可以用两个前缀和异或来表示。

现在问题就转化为了:在n个数中选取尽量多的数,使得这些数的任意子集的异或和不为0。

这是个线性基的经典问题,关于线性基,可以参考下这篇博客:https://www.cnblogs.com/ljh2000-jump/p/5869991.html

线性基有几个性质,其中包括:一是线性基的任意子集异或和都不为0;二是线性基的任意子集异或和的值域等于原数的任意子集异或和的值域。

那么,最终的答案就是前缀异或和中线性基的个数。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+;
int a[N],p[N],sum[N];
int n;
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-]^a[i];
}
if(!sum[n]){
cout<<-;
return ;
}
for(int i=;i<=n;i++){
for(int j=;j>=;j--){
if(!((<<j)&sum[i])) continue ;
if(!p[j]){
p[j]=sum[i];
break ;
}
sum[i]^=p[j];
}
}
int ans = ;
for(int i=;i<;i++) if(p[i]) ans++;
cout<<ans;
return ;
}

Educational Codeforces Round 58 (Rated for Div. 2) 题解的更多相关文章

  1. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  2. Educational Codeforces Round 65 (Rated for Div. 2)题解

    Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...

  3. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  4. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

  5. Educational Codeforces Round 58 (Rated for Div. 2) F dp + 优化(新坑) + 离线处理

    https://codeforces.com/contest/1101/problem/F 题意 有n个城市,m辆卡车,每辆卡车有起点\(s_i\),终点\(f_i\),每公里油耗\(c_i\),可加 ...

  6. Educational Codeforces Round 58 (Rated for Div. 2) D 树形dp + 数学

    https://codeforces.com/contest/1101/problem/D 题意 一颗n个点的树,找出一条gcd>1的最长链,输出长度 题解 容易想到从自底向长转移 因为只需要g ...

  7. Educational Codeforces Round 58 (Rated for Div. 2) G 线性基

    https://codeforces.com/contest/1101/problem/G 题意 一个有n个数字的数组a[],将区间分成尽可能多段,使得段之间的相互组合异或和不等于零 题解 根据线性基 ...

  8. Educational Codeforces Round 58 (Rated for Div. 2)

    A. Minimum Integer 水 #include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using name ...

  9. Educational Codeforces Round 58 (Rated for Div. 2) (前两题题解)

    感慨 这次比较昏迷最近算法有点飘,都在玩pygame...做出第一题让人hack了,第二题还昏迷想错了 A Minimum Integer(数学) 水题,上来就能做出来但是让人hack成了tle,所以 ...

随机推荐

  1. Leecode刷题之旅-C语言/python-83删除排序链表中的重复元素

    /* * @lc app=leetcode.cn id=83 lang=c * * [83] 删除排序链表中的重复元素 * * https://leetcode-cn.com/problems/rem ...

  2. 2,PyAudio 实现录音 自动化交互实现问答

    Python 很强大其原因就是因为它庞大的三方库 , 资源是非常的丰富 , 当然也不会缺少关于音频的库 关于音频, PyAudio 这个库, 可以实现开启麦克风录音, 可以播放音频文件等等,此刻我们不 ...

  3. Hibernate-ORM:06.Hibernate中三种状态

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客主要叙述Hibernate中的三种状态:临时状态(瞬时状态),持久状态,游离状态 commit和flu ...

  4. VM打开虚拟机文件报错

    用VM打开以前的虚拟机文件报错 Cannot open the disk 'F:/****.vmdk' or one of the snapshot disks it depends on. 这种问题 ...

  5. GreenMail邮件测试服务器

    GreenMail邮件测试服务器 http://blog.csdn.net/jackiehff/article/details/8741988 这个目前没有需求,所以暂不研究

  6. 《python核心编程第二版》第2章习题

    2-1 略 2-1 略 2-2 (a)打印 结果是9 (b)9 (c)一样 (d)略 (e)略 2-3 略 2-4 (a) # /usr/bin/pythonraw_input() (b) # /us ...

  7. Linux服务架设篇--ping命令

    工作原理: 向远程机发送包含一定字节数的ICMP数据包,如果能收到对方的回复的数据包,就表明网络是相通的,而且根据两个数据包的时间差,还可以知道相互之间网络链接的速度. 注意: 有些远程主机由于某种原 ...

  8. Queue模块初识

    Queue模块实现了多生产者.多消费者队列.它特别适用于信息必须在多个线程间安全地交换的多线程程序中.这个模块中的Queue类实现了所有必须的锁语义.它依赖于Python中线程支持的可用性:参见thr ...

  9. c# mysql blob数据类型

    1.采用stream流形式写入: #region 数据流转换成blob类型数据写入数据库 static public bool StreamToBlob(ref Stream stream, Odbc ...

  10. java对数组的操作

    1 拷贝数组 数组全拷贝 数组定位拷贝 2 判断数组是否相等(每个元素都对应相等) 3 数组和集合的相互转化 import java.util.Arrays; import java.util.Lis ...