Educational Codeforces Round 64部分题解

A

题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下.

判断交点个数是否有限,如果有限,输出.

很明显当正方形套三角形或者三角形套正方形是交点个数是无限的(因为有一条边相交)

其他图形的嵌套交点个数比较好判断,不多赘述

但是注意坑点:

当按照矩形,园,三角这样的顺序是,三角与圆的一个交点是与圆和正方形的交点重合的,判一下就好了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cctype>
using namespace std;
int n;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 - 48 + ch;
ch = getchar();
}
return v * c;
}
int a[312312];
bool flag = 1;
int ans;
int main(){
n = read();
for(int i = 1;i <= n;++i) a[i] = read();
for(int i = 2;i <= n;++i){
if(a[i] == 2 && a[i - 1] == 3) flag = 0;
if(a[i] == 3 && a[i - 1] == 2) flag = 0;
if(a[i] == 1){
if(a[i - 1] == 2) ans += 3;
if(a[i - 1] == 3) ans += 4;
}
if(a[i] == 2){
if(a[i - 1] == 1) ans += 3;
if(i > 2 && a[i - 2] == 3) ans--;
}
if(a[i] == 3 && a[i - 1] == 1){
ans += 4; }
}
if(flag) printf("Finite\n%d\n",ans);
else printf("Infinite\n");
return 0;
}

B

题目大意:给定一个字符串,将其重新排序,使得任意两个相邻的字母在字母表上不相邻(\(a\)与\(z\)不相邻)

这道题当时卡了幸好unrated

很明显,我们将奇数字符和偶数字符分开考虑,这样就保证了奇数之间和偶数之间不会出现上述情况,唯一需要考虑的就是奇数和偶数的交接部分.我们想,如果奇数的最后一个和偶数的第一个相接或者偶数的第一个和奇数的最后一个 相接都不能满足,那么就无解(因为我们这样已经尽可能地去保障了他们不会出现上述情况)

代码先咕一咕吧

C

题目大意:给定\(n\)(偶数)个数,将\(n\)个数分为\frac{n}{2}对,求一种方案,使得最多的点对\((i,j)\)满足\(|{a_i-a_j}|>=k\)

求一个\(nlogn\)的做法

很明显的一个错误贪心:

排序之后,对于每个\(a_i\),都找到他后面第一个\(a_j\)使得\(a_j-a_i>=k\),这些操作直接在\(multiset\)(我当时手写FHQ也是没谁了)上搞一搞就好了

但是,很明显是错的.

看下面一组数据

10 2

1 2 3 4 5 6 7 8 9 10答案为\(5\)

但是用上述方法答案是\(4\)

之后我们发现,我们排完序之后,答案最多为\(\frac{n}{2}\)(下取整),所以至少将前\(\frac{n}{2}\)个与后\(\frac{n}{2}\)个去匹配(很明显随着第一个指针右移,第二个也会右移),这个直接维护双指针,维护当前可用的最小的\(p\)就好了

#include<cstdio>
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N = 2e5 + 3;
int a[N];
int n,k,ans;
int main(){
scanf("%d%d",&n,&k); int p = n / 2 + 1;
for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
sort(a + 1,a + n + 1);
for(int i = 1;i <= n / 2;++i){
for(;p <= n;++p)
if(a[p] - a[i] >= k) break; if(p > n) break;
ans++;p++;
}
printf("%d\n",ans);
return 0;
}

D

题目大意:给定一个边权为\(0/1\)的树,求出满足从\(x\)点到\(y\)点不会出现经过边权为\(1\)的边之后在经过边权为\(0\)的边的点对\((x,y)\)的个数

要求一个\(nlogn\)或者更优的算法

这道题听说可以用\(dsu\)去做,以后再学(flag)

我们考虑\(dp\)

设\(dp_{i,0/1}\)表示以\(i\)点为根时,只经过边权为\(0/1\)的边就到达\(i\)的点的个数

想一想,如果我们能够求出这个东西

那么

\(ans = \sum_{i = 1}^n dp_{i,0} * dp_{i,1} + dp_{i,0}+dp_{i,1}\)

所以难点在于计算出\(dp\)数组

先考虑在以\(i\)为根的子树中

很明显则有

\(dp_{i,w} = \sum_{j\in son_i}(dp_{j,w} + 1)\)

这样我们就可以求出在\(i\)的子树中的值了,但是我们想要的是其为根时候的\(dp\)值

那么我们进行第二遍\(dfs\),想一下

去推出由父亲到儿子的贡献

如果所有点到其父亲的路径是\(dp_{i,w}\)

那么到他自己也是\(dp_{i,w}\)(因为他们两个只有一条边的距离,且这条边的边权为\(w\))

在递归处理就好了

#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#define mk make_pair
#define pii pair<int,int>
#define LL long long
using namespace std;
const int N = 2e5 + 3;
vector <pii> G[N];
LL f[N][2];
int n;
inline void dfs1(int x,int fa){
for(int i = 0;i < G[x].size();++i){
int y = G[x][i].first,z = G[x][i].second;
if(y == fa) continue;
dfs1(y,x);
f[x][z] += f[y][z] + 1;
}
}
inline void dfs2(int x,int fa){
for(int i = 0;i < G[x].size();++i){
int y = G[x][i].first,z = G[x][i].second;
if(y == fa) continue;
f[y][z] = f[x][z];
dfs2(y,x);
}
}
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 - 48 + ch;
ch = getchar();
}
return v * c;
}
int main(){
n = read();
for(int i = 1;i < n;++i){
int x = read(),y = read(),z = read();
G[x].push_back(mk(y,z));
G[y].push_back(mk(x,z));
}
dfs1(1,0);
dfs2(1,0);
LL ans = 0;
for(int i = 1;i <= n;++i)
ans += f[i][0] * f[i][1] + f[i][0] + f[i][1];
cout << ans << endl;
return 0;
}

E

题目大意,给定一个\(n\)的排列,求出满足\(a_l+a_r=\max_{i = l}^ra_i\)的区间\([l,r]\)的个数

我们直接寻找最大值去分治,数据随机的话,是可以\(nlogn\)的,但是就跟着\(noip2019 D1T1\)一样,如果每次最大值都靠向两边,复杂度是会退化为\(n^2\)的

之后我们想如果对于每个\(a_i\),我们都求出以其为最大值的区间的最大左右端点\(l_i,r_i\),之后我们设其到\(l_i\)的距离为\(L\),

到\(r_i\)的距离为\(R\),我们可以找到一个\(T(n) = T(L) + T(R) + n\)的做法,这个很明显没有进行优化.

但是,我们想一下,以\(a_i\)为最大值的区间端点必须在$l_i,r_i $之间,那么我们每次找到 $ L,R$中较小的一个去进行枚举.

之后查询\(a_i - a_j\)的位置是否在相反的一边,这样的话时间复杂度变成了\(nlog(n)\)了

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<deque>
#define LL long long
using namespace std;
const int N = 2e5 + 45;
int pos[N];
int a[N],l[N],r[N];
int n;
deque <int> q;
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
int main(){
n = read();
for(int i = 1;i <= n;++i) a[i] = read(),pos[a[i]] = i;
for(int i = 1;i <= n;++i){
while(!q.empty() && a[q.back()] < a[i]) q.pop_back();
l[i] = q.empty() ? 1 : q.back() + 1;
q.push_back(i);
}
q.clear();
for(int i = n;i >= 1;--i){
while(!q.empty() && a[q.back()] < a[i]) q.pop_back();
r[i] = q.empty() ? n : q.back() - 1;
q.push_back(i);
}
LL ans = 0;
// for(int i = 1;i <= n;++i) printf("%d %d\n",l[i],r[i]);
for(int i = 1;i <= n;++i){
// printf("a[i]:%d %d %d\n",a[i],l[i],r[i]);
if(i - l[i] < r[i] - i){
for(int j = l[i];j < i;++j)
if(pos[a[i] - a[j]] <= r[i] && pos[a[i] - a[j]] > i) ans++;
// printf("%d %d\n",j,pos[a[i] - a[l[i]]]);
}
else{
for(int j = r[i];j > i;--j){
if(pos[a[i] - a[j]] >= l[i] && pos[a[i] - a[j]] < i) ans++;
}
}
}
cout << ans << endl;
return 0;
}

Educational Codeforces Round 64部分题解的更多相关文章

  1. Educational Codeforces Round 64 部分题解

    Educational Codeforces Round 64 部分题解 不更了不更了 CF1156D 0-1-Tree 有一棵树,边权都是0或1.定义点对\(x,y(x\neq y)\)合法当且仅当 ...

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

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

  3. Educational Codeforces Round 64(ECR64)

    Educational Codeforces Round 64 CodeForces 1156A 题意:1代表圆,2代表正三角形,3代表正方形.给一个只含1,2,3的数列a,ai+1内接在ai内,求总 ...

  4. Educational Codeforces Round 63部分题解

    Educational Codeforces Round 63 A 题目大意就不写了. 挺简单的,若果字符本来就单调不降,那么就不需要修改 否则找到第一次下降的位置和前面的换就好了. #include ...

  5. Educational Codeforces Round 64 (Rated for Div. 2) A,B,C,D,E,F

    比赛链接: https://codeforces.com/contest/1156 A. Inscribed Figures 题意: 给出$n(2\leq n\leq 100)$个数,只含有1,2,3 ...

  6. Educational Codeforces Round 64 -C(二分)

    题目链接:https://codeforces.com/contest/1156/problem/C 题意:给出n个数和整形数z,定义一对数为差>=z的数,且每个数最多和一个数组成对,求最多有多 ...

  7. Educational Codeforces Round 64 -B(贪心)

    题目链接:https://codeforces.com/contest/1156/problem/B 题意:给一段字符串,通过变换顺序使得该字符串不包含为位置上相邻且在字母表上也相邻的情况,并输出. ...

  8. Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)

    题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n  n个数,然后求有多少个区间[l,r] 满足    a[l]+a[r]=max([l, ...

  9. Educational Codeforces Round 64 选做

    感觉这场比赛题目质量挺高(A 全场最佳),难度也不小.虽然 unr 后就懒得打了. A. Inscribed Figures 题意 给你若干个图形,每个图形为三角形.圆形或正方形,第 \(i\) 个图 ...

随机推荐

  1. Python2.7下,调用subprocess启动子进程,读取子进程标准输出若干问题

    1:如果调用的子进程也是一个python脚本,则subprocess.Popen中的bufsize=1无效果.也就是说,即使设置了bufsize=1表示进行行缓冲,子进程如果不显示调用sys.stdo ...

  2. day18 jQuery,JavaScript高级&Django

    回顾: 整体: - HTML - CSS - JavaScript:基本数据类型:流程控制语句 - DOM - BOM:setInterval() - jQuery - 选择器 - 筛选器 - 内容和 ...

  3. 笔记:字体大小的几种不同的格式px,em,rem

    px px像素(Pixel),相对长度单位,像素px是相对于显示器屏幕分辨率而言的.(引自CSS2.0手册) 譬如,Windows的用户所使用的分辨率一般是96像素/英寸. 而MAC的用户所使用的分辨 ...

  4. GIAC2019 演讲精选 | 面向未来的黑科技——UI2CODE闲鱼基于图片生成跨端代码

    一直以来, 如何从‘视觉稿’精确的还原出 对应的UI侧代码 一直是端侧开发同学工作里消耗比较大的部分,一方面这部分的工作 比较确定缺少技术深度,另一方面视觉设计师也需要投入大量的走查时间,有大量无谓的 ...

  5. php配置文件php.ini中文详解

    转自:http://www.cnblogs.com/hbl/archive/2008/02/15/1069367.html [PHP] ; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而p ...

  6. 【Leetcode链表】两两交换链表中的节点(24)

    题目 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表.你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例: 给定 1->2->3->4, 你应该返回 2- ...

  7. NoSQL之简介

    简介 NoSQL(NoSQL=Not Only SQL),意即'不仅仅是"SQL".泛指非关系型的数据库.是一项全新的数据库革命性运动. 在现代的计算系统上每天网络上会产生庞大的数 ...

  8. Jmeter If控制器

    "${xxx}"=="1" 或者 "${xxx}"!="2"

  9. 2018-8-10-WPF-如何在绑定失败异常

    title author date CreateTime categories WPF 如何在绑定失败异常 lindexi 2018-08-10 19:16:53 +0800 2018-05-17 1 ...

  10. 十分钟学会 Fiddler

    一.Fiddler介绍 Fiddler是一个http抓包改包工具,fiddle英文中有"欺骗.伪造"之意,与wireshark相比它更轻量级,上手简单,因为只能抓http和http ...