bzoj3600 没有人的算术
查询可以直接线段树维护,修改呢,考虑一颗替罪羊,每个点代表一段区间,他的$val$就是区间中值,线段树记录对应节点的$id$,再开一个数组记录即时的权值,因为重建时$val$可能会变。这好像是重量平衡树的应用,然而究竟什么是重量平衡树呢?
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define inf 0x3fffffffffffffff 7 #define alp 0.75 8 #define N 500050 9 using namespace std; 10 double a[500050]; 11 int tot; 12 struct Node{ 13 Node *ch[2]; 14 double l,r; 15 int size,cover,ex,k1,k2,id; 16 void pushup(){ 17 size=ch[0]->size+ch[1]->size+ex; 18 cover=ch[0]->cover+ch[1]->cover+1; 19 } 20 bool bad(){ 21 return ch[0]->cover>=cover*alp+5||ch[1]->cover>=cover*alp+5; 22 } 23 Node(double x,double y,int z,int w,int k); 24 }*null=new Node(0,0,0,0,0),*root,*sta[N]; 25 int len; 26 Node:: Node(double x,double y,int z,int w,int k){ 27 l=x;r=y;k1=z;k2=w;id=k; 28 a[k]=(l+r)/2.0; 29 size=cover=ex=1; 30 ch[0]=ch[1]=null; 31 } 32 void init(){ 33 null->ch[0]=null->ch[1]=null; 34 null->l=null->r=null->k1=null->k2=null->id=0; 35 null->size=null->cover=null->ex=0; 36 a[0]=-5000000000000000000; 37 root=new Node(-inf,inf,0,0,++tot); 38 } 39 Node **insert(Node *&rt,double l,double r,int k1,int k2){ 40 if(rt==null){ 41 rt=new Node(l,r,k1,k2,++tot); 42 return &null; 43 } 44 rt->size++;rt->cover++; 45 Node **ret; 46 if(a[rt->k1]<a[k1]||(a[rt->k1]==a[k1]&&a[rt->k2]<a[k2]))ret=insert(rt->ch[1],(rt->l+rt->r)/2.0,rt->r,k1,k2); 47 else ret=insert(rt->ch[0],rt->l,(rt->l+rt->r)/2.0,k1,k2); 48 if(rt->bad())ret=&rt; 49 return ret; 50 } 51 void travel(Node *rt){ 52 if(rt==null)return; 53 travel(rt->ch[0]); 54 if(rt->ex){ 55 sta[++len]=rt; 56 travel(rt->ch[1]); 57 } 58 else{ 59 travel(rt->ch[1]); 60 delete rt; 61 } 62 } 63 Node * divide(int l,int r,double L,double R){ 64 if(l>r)return null; 65 int mid=(l+r)>>1; 66 sta[mid]->l=L;sta[mid]->r=R;a[sta[mid]->id]=(L+R)/2.0; 67 sta[mid]->ch[0]=divide(l,mid-1,L,(L+R)/2.0); 68 sta[mid]->ch[1]=divide(mid+1,r,(L+R)/2.0,R); 69 sta[mid]->pushup(); 70 return sta[mid]; 71 } 72 void rebuild(Node *&rt){ 73 double L=rt->l,R=rt->r; 74 len=0;travel(rt); 75 rt=divide(1,len,L,R); 76 } 77 void insert(int k1,int k2){ 78 Node **p=insert(root,-inf,inf,k1,k2); 79 if(*p!=null)rebuild(*p); 80 } 81 Node *find(Node *rt,int k1,int k2){ 82 if(rt==null)return rt; 83 if(rt->ex&&a[rt->k1]==a[k1]&&a[rt->k2]==a[k2])return rt; 84 if(a[rt->k1]<a[k1]||(a[rt->k1]==a[k1]&&a[rt->k2]<a[k2]))return find(rt->ch[1],k1,k2); 85 else return find(rt->ch[0],k1,k2); 86 } 87 88 int w[N],maxn[N],maxpos[N]; 89 void pushup(int rt){ 90 if(a[maxn[rt<<1]]>=a[maxn[rt<<1|1]]) 91 maxn[rt]=maxn[rt<<1], 92 maxpos[rt]=maxpos[rt<<1]; 93 else maxn[rt]=maxn[rt<<1|1], 94 maxpos[rt]=maxpos[rt<<1|1]; 95 } 96 void build(int rt,int l,int r){ 97 if(l==r){maxn[rt]=w[l];maxpos[rt]=l;return ;} 98 int mid=(l+r)>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r); 99 pushup(rt); 100 } 101 void update(int rt,int l,int r,int x,int y){ 102 if(l==r){maxn[rt]=y;maxpos[rt]=l;return ;} 103 int mid=(l+r)>>1; 104 if(x<=mid)update(rt<<1,l,mid,x,y); 105 else update(rt<<1|1,mid+1,r,x,y); 106 pushup(rt); 107 } 108 int MX,POS; 109 void query(int rt,int l,int r,int x,int y){ 110 if(x<=l&&r<=y){ 111 if(a[MX]<a[maxn[rt]]) 112 MX=maxn[rt],POS=maxpos[rt]; 113 return; 114 } 115 int mid=(l+r)>>1; 116 if(x<=mid)query(rt<<1,l,mid,x,y); 117 if(y>mid)query(rt<<1|1,mid+1,r,x,y); 118 } 119 120 int n,m; 121 int main(){ 122 init(); 123 scanf("%d%d",&n,&m); 124 for(int i=1;i<=n;i++)w[i]=1; 125 build(1,1,n); 126 char ch[2]; 127 int x,y,z,l,r; 128 while(m--){ 129 scanf("%s",ch); 130 if(ch[0]=='C'){ 131 scanf("%d%d%d",&x,&y,&z); 132 Node *now=find(root,w[x],w[y]); 133 if(now!=null)w[z]=now->id; 134 else{insert(w[x],w[y]);w[z]=tot;} 135 update(1,1,n,z,w[z]); 136 } 137 if(ch[0]=='Q'){ 138 scanf("%d%d",&l,&r); 139 MX=POS=0;query(1,1,n,l,r); 140 printf("%d\n",POS); 141 } 142 } 143 return 0; 144 }
View Code
转载于:https://www.cnblogs.com/Ren-Ivan/p/8287680.html
bzoj3600 没有人的算术相关推荐
- [BZOJ3600]没有人的算术
咕了这么久终于把这题补回来了... 关键在于怎么维护"数"的大小,直接用平衡树即可,每个平衡树节点维护的是一个实数区间$[l,r]$,那么$mid$就是这个节点所代表的" ...
- 基于modelsim的十个Verilog入门试验程序(1)(7人表决器+算术逻辑单元)—程序+测试代码+波形+结果分析
内容 实验一:7人表决器的设计 实验二:算数逻辑单元的设计 实验三:JK触发器的设计 实验四:环形计数器的设计 实验五:顺序排列的设计 实验六:二进制除法器的设计 实验七:数字显示频率计的设计 实验八 ...
- 省选之前的未完成的计划(截至到省选)
PLAN OF THE COMING HEOI good problems: -bzoj4823:[Cqoi2017]老C的方块 [*] -bzoj3171:[Tjoi2013]循环格 [*] -bz ...
- 3682: Phorni 后缀平衡树 线段树
国际惯例的题面: 考虑如果没有强制在线我们能怎么水掉这个题,先构造出字符串,各种方法求一下后缀数组,然后线段树维护区间rank最小的位置即可. 然而他要求强制在线,支持插入后缀,并比较后缀大小(求ra ...
- 2019年7月训练记录(更新ing)
前言 本月上半月训练记录可详见:2019年暑假绍兴集训. \(Jul\ 15th\) 早上到机房先做了一道一直想做的板子题:[洛谷4781][模板]拉格朗日插值,发现拉格朗日插值也并没有想象中那么难. ...
- c语言实验一的错误,C语言实验(三)
第四章分支结构实验 实验项目:第四章实验设计 实验项目:4.3.1 if语句的应用 ,4.3.2 switch case的应用 ,4.3.3 switch case嵌套if语句的应用 ,4.3. ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
- Kill Math: 让数学不只是符号
Kill Math: 让数学不只是符号 Author: Bret Victor / April 11, 2011 译者:神奇的战士 Bret Victor 是苹果公司的前 IPAD 的交互设计师, 大 ...
- 【苏格拉底言行录】 第四卷
[第 四 卷] 『第 一 章』 苏格拉底喜欢和青年人交往:他是怎样鉴别青年人的,他希望青年人受到良好的教育,第1.2节.如果受的教育不好,青年人的意志越坚强,就越容易犯罪,第3.4节.幸福不在于财富, ...
最新文章
- python中文名的发件人邮件读取解析_如何使用python收取读取邮件?
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件。...
- 皮一皮:这是结婚还是华山论剑...
- linux i2c子系统入口,I2C子系统1 - ARM_Linuxx的个人空间 - OSCHINA - 中文开源技术交流社区...
- 从零开始搭建spring-cloud(1) ----eureka
- 比较第一与第二个字符串,是否有连续的5个字符相同.sql
- MIDDLEWARE 在传输大量数据时,经常会发生堵塞,如果有一条错误的数据整个队列将无法处理
- word 中同样的字号和行距倍数,不一样的行距
- 2021华为杯建模---总结
- 面试题 04.08. 首个共同祖先
- 2008安装完了找不到_防臭地漏哪种好?防臭地漏怎么安装?一篇文章全了解
- 精通那么多技术,你为何还是受不到重用?
- 使用appium时出现的问题
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Java2实用教程第五版课后习题解析(持续更新,适合初学者)
- Mac乐谱制作工具---Sibelius 8 for Mac西贝柳斯
- cmd下批量pingIP地址
- 行业知识图谱调查报告(一):知识图谱概述
- microusb贴片 ad封装_diy从pcb到焊接,到程序调试,真正意思上的diy机械键盘pcb由ad绘制...
- 停止内耗:过一个不累的人生-读书笔记
热门文章
- C++ stack容器
- hive分区用2个字段有何限制_[Hive]新增字段(column)后,旧分区无法更新数据问题...
- python怎么做界面自动化_mac+python3+selenium做pc的界面自动化测试
- HDLBits 系列(7)对for循环以及generate for的各种实践
- 【FPGA】SRIO例子程序仿真分析实践
- Redis Labs再次修改许可,没用几个月的Commons Clause或被删除
- P5147 随机数生成器 [数列]
- zabbix添加URL监控
- 用树莓派做一个alibaba-guest
- 深入理解C#第三版部分内容