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)是区间[ ...
随机推荐
- ubuntu 上的ruby安装
安装 rbenv git clone git://github.com/sstephenson/rbenv.git ~/.rbenv # 用来编译安装 ruby git clone git://git ...
- Consul做服务发现
使用Consul做服务发现的若干姿势 https://www.cnblogs.com/bossma/p/9756809.html 从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后 ...
- 【BZOJ2850】巧克力王国 KDtree
[BZOJ2850]巧克力王国 Description 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜 欢过于甜的巧克力.对于每一块巧克力,我们设 ...
- 前端工程师面试问题归纳(二、问答类JQ相关)
其他随笔 前端工程师面试问题归纳(一.问答类html/css/js基础) 前端工程师面试问题归纳(三.代码类) 1. jQuery 库中的 $() 是什么? $() 函数是 jQuery() 函数的别 ...
- openfaas 了解
1. 官方介绍 OpenFaaS (Functions as a Service) is a framework for building serverless functions with Dock ...
- C#检测应用程序重复启动----函数检测(可以在多用户登录情况下检测)
上文是在网上找的检测程序重复运行的类,但是感觉不是很好用,而且还使用了API,似乎完全没有必要,于是晚上自己写了一个函数,经过测试,在多用户下仍然可以检测到程序的多次运行.当然,如果程序改了名字还是可 ...
- zabbix 3.0.2自定义脚本
http://blog.51cto.com/xiao987334176/1769766 有一个通知队列,如果超过了一定的值,就需要报警一下 查询接口可以返回队列的数量,格式是json,data后面的数 ...
- DHCP(二)
提供阶段:即DHCP服务器向DHCP客户端提供预分配IP地址的阶段.网络中的所有DHCP服务器接收到客户端的DHCP Discover报文后,都会根据自己地址池中IP地址分配的优先次序选出一个IP地址 ...
- java代码练习======每隔5行打印数字
总结:当我们感觉数字排列横排,竖排不好看的时候,学会空几行在排列,哎呦,效果不错喔 package com.aa; public class West2 { public static void ma ...
- mysql 无意重启 [Note] /usr/sbin/mysqld: Normal shutdown
情况: 今早发现,昨天下午安装的4台mysql服务器,突然出现,由于在shell窗口 (root@localhost:mysql.sock) [(none)]> 190102 18:12:16 ...