当前位置: 首页 > news >正文

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,感谢指点)

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <vector>
  6 
  7 using namespace std;
  8 const int maxn=100000+10;
  9 int T,n,m;
 10 struct Node{
 11     int l,r,num;
 12 }node[maxn];
 13 int x,l,k;
 14 int set[4*maxn],num[maxn];
 15 void pushdown(int o){
 16     if(set[o]){
 17         set[2*o]=set[o];
 18         set[2*o+1]=set[o];
 19         set[o]=0;
 20     }
 21 }
 22 int ql,qr,c;
 23 void update(int o,int L,int R){
 24     if(ql<=L&&qr>=R){
 25         set[o]=c;
 26         return;
 27     }
 28     pushdown(o);
 29     int M=L+(R-L)/2;
 30     if(ql<=M)
 31     update(2*o,L,M);
 32     if(qr>M)
 33     update(2*o+1,M+1,R);
 34     return ;
 35 }
 36 int ask(int o,int L,int R,int p){
 37     if(L==R){
 38         return set[o];
 39     }
 40     pushdown(o);
 41     int M=L+(R-L)/2;
 42     if(p<=M)
 43         return ask(2*o,L,M,p);
 44     else
 45         return ask(2*o+1,M+1,R,p);
 46 }
 47 //*******以下是第二棵线段树
 48 int sum[4*maxn],addv[4*maxn];
 49 void pushdown2(int o){
 50     if(addv[o]){
 51         addv[2*o]+=addv[o];addv[2*o+1]+=addv[o];
 52         sum[2*o]+=addv[o];sum[2*o+1]+=addv[o];
 53         addv[o]=0;
 54     }
 55     return ;
 56 }
 57 
 58 void update2(int o,int L,int R){
 59     if(ql<=L&&qr>=R){
 60         addv[o]+=c;
 61         sum[o]+=c;
 62         return ;
 63     }
 64     pushdown2(o);
 65     int M=L+(R-L)/2;
 66     if(ql<=M)
 67         update2(2*o,L,M);
 68     if(qr>M)
 69         update2(2*o+1,M+1,R);
 70     return;
 71 }
 72 int ask2(int o,int L,int R,int p){
 73     if(L==R)return sum[o];
 74     int M=L+(R-L)/2;
 75     pushdown2(o);
 76     if(p<=M)
 77         return ask2(2*o,L,M,p);
 78     else
 79         return ask2(2*o+1,M+1,R,p);
 80 }
 81 struct Interval{
 82     int l,r;
 83 };
 84 vector<Interval>V1[maxn];
 85 vector<int>V2[maxn];
 86 int M,ans;
 87 int main(){
 88     scanf("%d",&T);
 89     for(int t=1;t<=T;t++){
 90         M=-1,ans=0;
 91         scanf("%d%d",&n,&m);
 92         for(int i=0;i<maxn;i++)V1[i].clear();
 93         for(int i=0;i<maxn;i++)V2[i].clear();
 94 
 95         memset(set,0,sizeof(set));
 96         for(int i=1;i<=m;i++){
 97             scanf("%d%d%d",&x,&l,&k);
 98             node[i].l=max(1,x-k);
 99             node[i].r=min(n,x+k);
100             node[i].num=l;
101             M=max(M,node[i].num);
102             V1[node[i].num].push_back((Interval){node[i].l,node[i].r});
103             ql=node[i].l,qr=node[i].r,c=node[i].num;
104             update(1,1,n);
105         }
106         for(int i=1;i<=n;i++){
107             int g=ask(1,1,n,i);
108            // cout<<i<<" "<<g<<endl;
109             V2[g].push_back(i);
110         }
111 
112         memset(sum,0,sizeof(sum));
113         memset(addv,0,sizeof(addv));
114     /*    for(int i=1;i<=M;i++){
115             printf("%d :",i);
116             for(int j=0;j<V2[i].size();j++){
117                 printf("%d ",V2[i][j]);
118             }
119             printf("\n");
120         }*/
121         for(int i=1;i<=M;i++){
122           //  cout<<i<<endl;
123             for(int j=0;j<V1[i].size();j++){
124                 Interval inter=V1[i][j];
125                 ql=inter.l,qr=inter.r,c=1;
126                 update2(1,1,n);
127             }
128             for(int j=0;j<V2[i].size();j++){
129                 if(ask2(1,1,n,V2[i][j])>=2){
130                    // printf("%d %d\n",V2[i][j],ask2(1,1,n,V2[i][j]));
131                     ans++;
132                 }
133             }
134             for(int j=0;j<V1[i].size();j++){
135                 Interval inter=V1[i][j];
136                 ql=inter.l,qr=inter.r,c=-1;
137                 update2(1,1,n);
138             }
139         }
140         printf("%d\n",ans);
141     };
142 return 0;
View Code

 

转载于:https://www.cnblogs.com/LQLlulu/p/8850129.html

相关文章:

  • thinkphp5项目--企业单车网站(七)
  • Go初接触之image
  • linux系统安装telnet服务
  • ztree连接数据库,实现下拉菜单
  • c++之enum的好处与 define 的区别
  • 利用itext导出PDF的小例子
  • Linux 防火墙开放特定端口 (iptables)
  • kafka知识体系-kafka数据可靠性和一致性保证
  • 结对编程收获
  • Ojective-C学习笔记(4)关于面向对象编程
  • I函数
  • 猫狗大战
  • 洛谷 2055 BZOJ 1433 [ZJOI2009]假期的宿舍
  • UVA 10891 Game of Sum(区间DP(记忆化搜索))
  • Python学习4,字符串
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • Brief introduction of how to 'Call, Apply and Bind'
  • ComponentOne 2017 V2版本正式发布
  • CSS实用技巧干货
  • input实现文字超出省略号功能
  • Java读取Properties文件的六种方法
  • Laravel核心解读--Facades
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • OSS Web直传 (文件图片)
  • PHP 的 SAPI 是个什么东西
  • 从零开始学习部署
  • 多线程 start 和 run 方法到底有什么区别?
  • - 概述 - 《设计模式(极简c++版)》
  • 前端js -- this指向总结。
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • FaaS 的简单实践
  • 国内开源镜像站点
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​水经微图Web1.5.0版即将上线
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #if #elif #endif
  • #Linux(make工具和makefile文件以及makefile语法)
  • #图像处理
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (2)Java 简介
  • (LeetCode 49)Anagrams
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)linux使用docker容器运行mysql
  • (转)Oracle存储过程编写经验和优化措施
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET 命令行参数包含应用程序路径吗?
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [Android 13]Input系列--获取触摸窗口
  • [Android] Amazon 的 android 音视频开发文档
  • [Android]How to use FFmpeg to decode Android f...