Gym101350 FMonkeying Around
题意
有n只猴子排成一排,一共有m个笑话。开始时,这些猴子都坐在椅子上。下面m行给出的每个笑话包含三个整数x,l,k。代表猴子x讲了笑话l,所以距离x小于等于k的猴子如果他们从没听过这个笑话,他们会掉下椅子,如果听过这个笑话他们会爬回椅子上。问在讲完m个笑话以后,还有哪些猴子是还坐在椅子上的。
分析
当时在场上想到了是线段树,但是总是想保存下每个猴子听每个笑话听了几遍,发现数组都开不下,很难受。。
我们来看大佬们的想法:
对于每只猴子,它是在椅子上还是在地上只取决于它听到的最后一个笑话一共听了几遍。
所以我们首先要找出每只猴子听到的最后一个笑话是什么,然后再找出这个笑话他听了几遍。
我们可以想到用两颗线段树分别求这两个东西。第一颗线段树是比较好想的,关键是第二颗。
假设我们现在已经知道了每只猴子听到的最后一个笑话是什么。
对于每个笑话,我们在一颗线段树上做,做完以后删除。然后统计最后一个听到的笑话是这个的人的听的次数。这样遍历笑话和猴子,均摊是O(n)的,线段树的操作是logn(这段话来自大佬:https://www.cnblogs.com/huibixiaoxing/p/7678842.html,感谢指点)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector> using namespace std;
const int maxn=+;
int T,n,m;
struct Node{
int l,r,num;
}node[maxn];
int x,l,k;
int set[*maxn],num[maxn];
void pushdown(int o){
if(set[o]){
set[*o]=set[o];
set[*o+]=set[o];
set[o]=;
}
}
int ql,qr,c;
void update(int o,int L,int R){
if(ql<=L&&qr>=R){
set[o]=c;
return;
}
pushdown(o);
int M=L+(R-L)/;
if(ql<=M)
update(*o,L,M);
if(qr>M)
update(*o+,M+,R);
return ;
}
int ask(int o,int L,int R,int p){
if(L==R){
return set[o];
}
pushdown(o);
int M=L+(R-L)/;
if(p<=M)
return ask(*o,L,M,p);
else
return ask(*o+,M+,R,p);
}
//*******以下是第二棵线段树
int sum[*maxn],addv[*maxn];
void pushdown2(int o){
if(addv[o]){
addv[*o]+=addv[o];addv[*o+]+=addv[o];
sum[*o]+=addv[o];sum[*o+]+=addv[o];
addv[o]=;
}
return ;
} void update2(int o,int L,int R){
if(ql<=L&&qr>=R){
addv[o]+=c;
sum[o]+=c;
return ;
}
pushdown2(o);
int M=L+(R-L)/;
if(ql<=M)
update2(*o,L,M);
if(qr>M)
update2(*o+,M+,R);
return;
}
int ask2(int o,int L,int R,int p){
if(L==R)return sum[o];
int M=L+(R-L)/;
pushdown2(o);
if(p<=M)
return ask2(*o,L,M,p);
else
return ask2(*o+,M+,R,p);
}
struct Interval{
int l,r;
};
vector<Interval>V1[maxn];
vector<int>V2[maxn];
int M,ans;
int main(){
scanf("%d",&T);
for(int t=;t<=T;t++){
M=-,ans=;
scanf("%d%d",&n,&m);
for(int i=;i<maxn;i++)V1[i].clear();
for(int i=;i<maxn;i++)V2[i].clear(); memset(set,,sizeof(set));
for(int i=;i<=m;i++){
scanf("%d%d%d",&x,&l,&k);
node[i].l=max(,x-k);
node[i].r=min(n,x+k);
node[i].num=l;
M=max(M,node[i].num);
V1[node[i].num].push_back((Interval){node[i].l,node[i].r});
ql=node[i].l,qr=node[i].r,c=node[i].num;
update(,,n);
}
for(int i=;i<=n;i++){
int g=ask(,,n,i);
// cout<<i<<" "<<g<<endl;
V2[g].push_back(i);
} memset(sum,,sizeof(sum));
memset(addv,,sizeof(addv));
/* for(int i=1;i<=M;i++){
printf("%d :",i);
for(int j=0;j<V2[i].size();j++){
printf("%d ",V2[i][j]);
}
printf("\n");
}*/
for(int i=;i<=M;i++){
// cout<<i<<endl;
for(int j=;j<V1[i].size();j++){
Interval inter=V1[i][j];
ql=inter.l,qr=inter.r,c=;
update2(,,n);
}
for(int j=;j<V2[i].size();j++){
if(ask2(,,n,V2[i][j])>=){
// printf("%d %d\n",V2[i][j],ask2(1,1,n,V2[i][j]));
ans++;
}
}
for(int j=;j<V1[i].size();j++){
Interval inter=V1[i][j];
ql=inter.l,qr=inter.r,c=-;
update2(,,n);
}
}
printf("%d\n",ans);
};
return ;
Gym101350 FMonkeying Around的更多相关文章
- gym101350 c h m
C. Cheap Kangaroo time limit per test 1.0 s memory limit per test 256 MB input standard input output ...
- Gym101350 J Lazy Physics Cat
参考博客:https://blog.csdn.net/lengqiu2015/article/details/76855681#reply 题意 给出一个长度为n的01串 我们定义F(x,y)是区间[ ...
随机推荐
- rebar自定义template
在开发过程中rebar自带模板建立项目,或多或少不能满足自己的开发需求.本人又是那种懒人,所以就要想办法偷懒.查看了priv模板 打造适合自己的项目模板.下面我简单的介绍整个模板的打造过程. 准备过程 ...
- 剑指offer-第四章解决面试题的思路(二叉树的镜像)
题目:请完成函数,输入一个二叉树,该函数输出它的镜像. 思路:可能没有听说过书的镜像,但是可以通过画图等来找灵感.就像照镜子一样,人的左边和右边交换了. 如图: 通过如下图变化就可以由左图得到右图: ...
- WCF NetTcpBinding 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作
背景:WindowsService + WCF + NetTcpBinding 之前一直使用http协议模式,改为net.tcp之后隔段时间出现:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操 ...
- [BZOJ5133][CodePlus2017年12月]白金元首与独舞
bzoj luogu 题意 给你一个\(n*m\)的网格,每个位置上有一个箭头指向上或下或左或右.有些位置上还没有箭头,现在要求你在这些没有箭头的位置上填入箭头,使得从网格的任意一个位置开始,都可以沿 ...
- wifi文件传输
步骤: 1.下载CocoaHTTPServer 2.解压后,将CocoaHTTPServer-master目录下的Core导入工程. 3.打开Samples/SimpleFileUploadServe ...
- gradle 安装试用
1. java 环境(jdk 6 以上,最好使用8以及以上) yum install -y java-1.8.0-openjdk-devel 2. 基本配置 // path 路径 export PAT ...
- vue-router linkActiveClass问题
在使用vue做移动端的时候,底部四个菜单中当前菜单需要高亮显示,但是由于路由配置的问题导致了下图中的问题: # 首页会一直常亮,不论是否有点击(路由配置如右图) 经过排查,发现问题出现在router中 ...
- Python函数- setattr()
作用: setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在. 语法: setattr(object, name, value) object -- 对象. name -- ...
- Python学习系列(四)(列表及其函数)
Python学习系列(四)(列表及其函数) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) Python学习系列(三)(字符串) 一.基本概念 1,列表是什么? ...
- 客户端如何调用WebService并且POST数据
直接上代码 using System; using System.Collections.Generic; using System.Linq; using System.Text;using Sys ...