NBUT 1120 Reimu's Teleport (线段树)
题意:
有n个格子,一开始全部面向top。接下来的每次修改F a b ,如果 a>b则将a~b之间的格子全面置为向右,否则置为向左。对于每个询问Q输出向左、top、右的数量。
思路:
普通线段树。每个结点中保存三个值,分别对应3个方向的数量。要设置一下lazy_tag以减少时间消耗,因为有可能Q远少于F,那么一直在更改,大多可能不需要改到,暂时不更新,询问时要用到再更新。每次一改就整个区间都是一个方向,所以当有tag时可以往下推各占多少。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int ans[3];//答案 4 struct node 5 { 6 bool tag; 7 int num[3]; 8 node *ll,*rr; 9 node() 10 { 11 tag=false; 12 num[0]=num[1]=num[2]=0; 13 ll=rr=0; 14 } 15 }; 16 17 node * built(int LL, int RR) 18 { 19 node *tmp=new(node); 20 if(LL==RR) 21 { 22 tmp->num[1]=1; 23 return tmp; 24 } 25 int mid=(LL+RR)>>1; 26 tmp->ll=built(LL,mid); 27 tmp->rr=built(mid+1,RR); 28 tmp->num[1]+=tmp->ll->num[1]+tmp->rr->num[1]; //开始只需要更新向上的 29 return tmp; 30 } 31 32 void modify( node *t,int LL,int RR,int mid)//专门修改统计数量 33 { 34 if(t->num[0]) 35 { 36 t->ll->num[0]=mid+1-LL; 37 t->ll->num[1]=t->ll->num[2]=0; 38 t->rr->num[0]=RR-mid; 39 t->rr->num[1]=t->rr->num[2]=0; 40 } 41 if(t->num[1]) 42 { 43 t->ll->num[1]=mid+1-LL; 44 t->ll->num[0]=t->ll->num[2]=0; 45 t->rr->num[1]=RR-mid; 46 t->rr->num[0]=t->rr->num[2]=0; 47 } 48 if(t->num[2]) 49 { 50 t->ll->num[2]=mid+1-LL; 51 t->ll->num[0]=t->ll->num[1]=0; 52 t->rr->num[2]=RR-mid; 53 t->rr->num[0]=t->rr->num[1]=0; 54 } 55 } 56 57 void update(int ll,int rr,int LL,int RR,int c,node *t) 58 { 59 if(ll==LL&&rr==RR) 60 { 61 t->tag=true; 62 if(c==0) 63 { 64 t->num[0]=RR-LL+1; 65 t->num[1]=t->num[2]=0; 66 } 67 else 68 { 69 t->num[2]=RR-LL+1; 70 t->num[0]=t->num[1]=0; 71 } 72 return; 73 } 74 int mid=(LL+RR)>>1; 75 76 if(t->tag) 77 { 78 t->tag=false; 79 t->ll->tag=t->rr->tag=true; 80 modify(t,LL,RR,mid); 81 } 82 if(ll>mid) //右边 83 update(ll,rr,mid+1,RR,c,t->rr); 84 else if(rr<=mid) //左边 85 update(ll,rr,LL,mid,c,t->ll); 86 else 87 { 88 update(ll, mid, LL, mid, c,t->ll); 89 update(mid+1,rr,mid+1,RR,c,t->rr); 90 } 91 t->num[0]=t->ll->num[0]+t->rr->num[0]; 92 t->num[1]=t->ll->num[1]+t->rr->num[1]; 93 t->num[2]=t->ll->num[2]+t->rr->num[2]; 94 } 95 96 97 98 void query(int ll,int rr,int LL,int RR,node* t) 99 { 100 if(ll==LL && rr==RR) 101 { 102 ans[0]+=t->num[0]; 103 ans[1]+=t->num[1]; 104 ans[2]+=t->num[2]; 105 return; 106 } 107 int mid=((LL+RR)>>1); 108 if(t->tag) 109 { 110 t->tag=false; 111 t->ll->tag= t->rr->tag= true; 112 modify(t, LL, RR, mid); 113 } 114 115 if(ll>mid) query(ll,rr,mid+1,RR,t->rr); 116 else if(rr<=mid) query(ll,rr,LL,mid,t->ll); 117 else 118 { 119 query(ll, mid, LL, mid, t->ll); 120 query(mid+1,rr,mid+1,RR,t->rr); 121 } 122 123 } 124 125 126 int main() 127 { 128 //freopen("e://input.txt","r",stdin); 129 int a, t, e, r; 130 char ch; 131 132 while(cin>>a>>t) 133 { 134 node *tree=built(1,t); //建树 135 136 for(int i=0; i<a; i++) 137 { 138 cin>>ch; 139 scanf("%d %d", &e, &r); 140 if(ch=='F') //修改 141 { 142 if(e>r) update(r, e, 1, t, 0, tree); 143 else update(e, r, 1, t, 2, tree); 144 } 145 else //Q 查询 146 { 147 memset(ans,0,sizeof(ans)); 148 query(e,r,1,t,tree); 149 printf("%d %d %d\n",ans[0],ans[1],ans[2]); 150 } 151 } 152 } 153 return 0; 154 }
AC代码
转载于:https://www.cnblogs.com/xcw0754/p/4538835.html
NBUT 1120 Reimu's Teleport (线段树)相关推荐
- NOJ [1120] Reimu\'s Teleport
问题描述 Hakurei Reimu(はくれい·れいむ) has an ability - Teleport. She can transport herself from here to anywh ...
- 二逼平衡树——树套树(线段树套Splay平衡树)
题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...
- 线段树——HDU - 1698
题目含义 就是初始化一堆数为1 可以经过操作把一个区间的数都改变 并求这堆数的总大小 题目分析 有一个 #include<iostream> #include<stdio.h> ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横
不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...
- [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树
Holiday Painting 节日画画 bzoj-1582 Usaco-2009 Hol 题目大意:给定两个n*m的01网格图.q次操作,每次将第二个网格图的子矩阵全部变成0或1,问每一次操作后两 ...
- codefores 786B. Legacy(最短路,线段树优化拆点,好题)
题目链接 B. Legacy time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...
- 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
最新文章
- 【学习笔记】超简单的多项式反三角函数(含全套证明)
- 零知识证明实践教程,第二部分
- java 静态数据_Java 静态数据初始化的示例代码
- pythonselenium浮动框_python上selenium的弹框操作实现
- 中国房地产官媒爆乐视投资国贸地产,布局AI智能家居生态
- Python架构(二)
- matlab是以什么运算为基础,matlab基础练习题及答案讲解
- fatal: protocol error: bad line length character: No s原因
- python网络爬虫系列教程——python中urllib、urllib2、cookie模块应用全解
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_13-webpack研究-webpack入门程序...
- 第三方系统平台如何对接gooflow2.0
- 如何使用微软官方工具MediaCreationTool来制作Windows10启动盘
- spring boot学生课程考试系统的设计与实现毕业设计源码171548
- 清除此计算机中wps云盘,教大家Win10系统删除WPS网盘的方法,爱纯净官网
- 居然可以一键删除微博内容
- 说说家乡的旅游景点吧...
- java publisher_Publisher/Subscriber(发布/订阅者)消息模式开发流程
- 小程序标准版交易组件开启
- CUDA+ GTX1050ti电脑配置
- Lynis介绍与使用