Codeforces Round #419 (Div. 1) 补题 CF 815 A-E
技巧性很强的一道二分优化题
题意很简单 给定n个三元组,和三个维度的上限,问存在多少三元组,使得对于给定的n个三元组中的每一个,必有两个维度严格小于。
首先我们根据一个维度(c维)对n个三元组排序,然后枚举答案在这个维度的取值。
此时序列被分成了两个部分,前半部分 满足所有c大于等于i 后半部分满足所有c严格小于i(即已有一个维度小于)
通过累计,我们知道此时前半部a维的最大值ma和b维的最大值mb.
显然可能存在的三元组答案,必然首先满足a维和b维严格大于ma和mb.
后面我们考虑对于后半部分,即c严格小于i的部分,可能存在某些三元组 ai和bi非常大,以致于上边的答案不合法。
这时,我们想知道,对于ai大于ma的那些三元组,其对应的bi能有多大?
我们可以用一个mx数组提前统计这个值。
那么,当ai大到一定程度,其对应的bi就不可能大于mb了 我们可以二分找到这个边界ret
对于ma到ret这个范围的值,我们让第一维取其中的某个值,对应的第二维b有多少种可能呢?
所有ai大于当前值的对应的bi的最大值。 因为若ai小于当前值,就不需要保证第二维大于bi了。。
具体看代码吧 有点难以描述。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define maxn 500005
#define ll long long
using namespace std; ll sum[maxn],mx[maxn]; ll n,p,q,r; ll ans; struct note{
int a,b,c;
}a[maxn]; bool cmp(note i,note j){
return i.c>j.c;
} int main(){
scanf("%I64d%I64d%I64d%I64d",&n,&p,&q,&r);
fo(i,1,n) scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].c);
fo(i,1,n) mx[a[i].a]=max(mx[a[i].a],(ll)a[i].b+1);
fd(i,p,1) mx[i]=max(mx[i+1],mx[i]);//可能存在的最大b值
fo(i,1,p) sum[i]=sum[i-1]+(q-mx[i])+1;
ll ma=1,mb=1;
sort(a+1,a+n+1,cmp);
int wz=1;
fd(i,r,1) {
while (wz<=n && a[wz].c==i) {
ma=max(ma,a[wz].a+1ll);
mb=max(mb,a[wz].b+1ll);
wz++;
}
if (ma>p || mb>q) break;
int x=ma,y=p,ret=ma-1;
while (x<=y) {
int mid=(x+y) >> 1;
if (mx[mid]>=mb) {
x=mid+1;
ret=mid;
}
else y=mid-1;
}
ans+=sum[ret]-sum[ma-1]+1ll*(p-ret)*(q-mb+1);
}
cout<<ans;
return 0;
}
题意非常简单 不必赘述
整个过程其实是一个满二叉树的层次遍历,问我们遍历到的第k个元素是哪一个。对数复杂度
先给出遍历的二叉树 其规律非常明显

我们可以在对数时间内快速寻找到第k个节点,但是我们的空间不足以储存所有的节点信息。
那么怎么办呢? 我们首先判断这个节点在哪一个层次,即它与邻居的最短距离是多少。
然后我们再二分判断这个节点在整个序列中的位置,我们可以快速判断一个区间产生能够产生多少个距离为len的子节点。与k比较即可。
于是总的复杂度是二分套二分 即O(lognlogn)
这道题让我们深入理解了满二叉树的层次遍历
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
int main(){
scanf("%lld%lld",&n,&k);
if(k==1)return printf("1"),0;
if(k==2)return printf("%lld",n),0;
n-=2,k-=3;
map<ll,ll>f,g,nxt;
g[n]=1;
while(g.size()){
nxt.clear();
for(auto s:g)if(s.first)
f[-((s.first-1)>>1)]+=s.second,
nxt[(s.first)>>1]+=s.second,
nxt[(s.first-1)>>1]+=s.second;
g=nxt;
}
for(auto s:f){
//printf("[%d]",s.first);
if(s.second>k){//确定在哪一层
ll l=1,r=n,len=-s.first;
// printf("[%d]",len);
while(true){
if(((r-l)>>1)==len&&k==0)
return printf("%lld",((r-l)>>1)+1+l),0;
map<ll,ll>A,B,C;
ll mid=l+r>>1;
A[mid-l]=1;
B[(r-l)>>1]=1;
while(A.size()){
C.clear();
for(auto qs:A)if(qs.first)
B[(qs.first-1)>>1]+=qs.second,//
C[(qs.first)>>1]+=qs.second,
C[(qs.first-1)>>1]+=qs.second;
A=C;
}
// printf("[%d]",B[len]);
if(B[len]>k)r=mid-1;
else l=mid+1,k-=B[len];
}
} else k-=s.second;
}
}
Codeforces Round #419 (Div. 1) 补题 CF 815 A-E的更多相关文章
- Codeforces Round #412 Div. 2 补题 D. Dynamic Problem Scoring
D. Dynamic Problem Scoring time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- Codeforces Round #585 (Div. 2) [补题]
前言 2019.9.16 昨天下午就看了看D题,没有写对,因为要补作业,快点下机了,这周争取把题补完. 2019.9.17 这篇文章或者其他文章难免有错别字不被察觉,请读者还是要根据意思来读,不要纠结 ...
- Codeforces Round #615 (Div. 3) 补题记录
第一次搞CF,结果惨不忍睹...还是太菜了 A:要用到全部的钱,所以总数必须是3的倍数,而且初始状态下任意一人的钱数不能超过总数除以3,否则没法分了 (也就这个签到算是在我能力范围之内了....) # ...
- Codeforces Round #617 (Div. 3) 补题记录
1296A - Array with Odd Sum 题意:可以改变数组中的一个数的值成另外一个数组中的数,问能不能使数组的和是个奇数 思路:签到,如果本来数组的和就是个奇数,那就OK 如果不是,就需 ...
- Codeforces Round #786 (Div. 3) 补题记录
小结: A,B,F 切,C 没写 1ll 对照样例才发现,E,G 对照样例过,D 对照样例+看了其他人代码(主要急于看后面的题,能调出来的但偷懒了. CF1674A Number Transforma ...
- Codeforces Round #429 (Div. 2) 补题
A. Generous Kefa 题意:n个气球分给k个人,问每个人能否拿到的气球都不一样 解法:显然当某种气球的个数大于K的话,就GG了. #include <bits/stdc++.h> ...
- Codeforces Round #590 (Div. 3)补题
要想上2000分,先刷几百道2000+的题再说 ---某神 题目 E F 赛时是否尝试 × × tag math bitmask 难度 2000 2400 状态 ∅ √ 解 E 待定 F 传送门 第一 ...
- Codeforces Round #574 (Div. 2)补题
A. Drinks Choosing 统计每种酒有多少人偏爱他们. ki 为每种酒的偏爱人数. 输出ans = (n + 1)/2 > Σki / 2 ? (n + 1)/2 - Σki / ...
- Codeforces Round #378 (Div. 2) D题(data structure)解题报告
题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...
随机推荐
- 详解DNS,你真的懂吗?
what`s this ? 概念 域名系统(英文:DomainNameSystem,缩写:DNS)是互联网的一项服务.它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网.D ...
- java集合系列之LinkedList源码分析
java集合系列之LinkedList源码分析 LinkedList数据结构简介 LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含 ...
- 我理解的ios和android
近期着手了几个android和ios的项目,如今说下我的几个对他们的理解 从设计上来讲.我觉得android 它更像是个网页,一个页面跳到另外一个页面,两者之间的关联不是非常大,仅仅能传递一些简单的參 ...
- to_char(sysdate,'D')的用法
select to_char(sysdate,'D') from dual; 这周的第几天:Day of week (1–7) 1,2,3,4,5,6,7--注意:每星期的第1天是”星期日“ se ...
- 项目记录26--unity-tolua框架 View03-UIManager.lua
做为程序员要懂得假设保持健康,对电脑时间太长非常easy眼花,得脖子病,腰都疼,这星期六日组团到康宁去了,哈哈. 一个字"疼"!!!! 废话不多少,把UIManager.lua个搞 ...
- System V 信号量使用相关函数
System V 信号量 在提到Posix 信号量时,指的是二值信号量或计数信号量,而System V信号量指的是入了计数信号量集 二值信号量:其值为0或1,类似于互斥锁,资源被锁住时为0,资源可用为 ...
- Linux查看IP 网关 DNS
ifconfig查看IP: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFC ...
- PCH in Xcode 6
本文转载至 http://blog.csdn.net/wbdwsqwwn/article/details/40476151 新建文件 ⌘+N 选择 iOS/Mac -> Other -> ...
- 小程序多级下拉菜单demo
小程序多级下拉菜单demo - CSDN博客 https://blog.csdn.net/github_39371177/article/details/80251211
- java里类方法和实例方法
实例方法相对于静态方法(或者叫类方法)而言没有 static 前缀类般方法被对象拥有(也称之实例方法原因)特点定义时候前面没有 static 前缀本类直接调用时候必须也实例方法内否则调用前必须先实例出 ...