hdu_5818_Joint Stacks(线段树模拟)
题意:
给你两个栈,多了个合并操作,然后让你模拟
题解:
很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度均摊一下,让每个操作都是logn的,于是用上了线段树模拟。
线段树考虑染色,线段树的区间代表的是操作编号,0代表为A栈,1代表为B栈,每次merge 就把1到i这个区间染成指定颜色,然后pop就在线段树中找最右边的对应颜色的点。这样每次操作都是logn
不过官方题解给的是O(n)的解法,反正我是没想到的,感觉智商被压制。
第一份代码是线段树O(nlogn),第二份代码是数组模拟O(n)。也就只能快400ms
Joint Stacks
比较简单巧妙的一个做法是引入一个新的栈C,每次合并的时候就把A和B合并到C上,然后把A和B都清空. push还是按正常做,pop注意当遇到要pop的栈为空时,因为题目保证不会对空栈进行pop操作,所以这时应直接改为对C栈进行pop操作. 这样做因为保证每个元素最多只在一次合并中被处理到,pop和push操作当然也是每个元素只做一次,所以总复杂度是O(N)的. 另一种做法是用链表来直接模拟,复杂度也是O(N),但代码量稍大一些.
#include<bits/stdc++.h>
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define mst(a,b) memset(a,b,sizeof(a))
#define F(i,a,b) for(int i=a;i<=b;++i)
using namespace std; const int N=1e5+;
int n,tr[N<<],lazy[N<<],dt[N],now,ic=;
char op[],x[],y[]; inline void pd(int rt)
{
if(lazy[rt])
{
if(tr[rt<<])tr[rt<<]=lazy[rt],lazy[rt<<]=lazy[rt];
if(tr[rt<<|])tr[rt<<|]=lazy[rt],lazy[rt<<|]=lazy[rt];
lazy[rt]=;
}
} void update(int L,int R,int c,int l=,int r=n,int rt=)
{
if(l==r&&L==R){tr[rt]=c;return;}
if(L<=l&&r<=R)
{
if(tr[rt])tr[rt]=c,lazy[rt]=c;
return;
}
pd(rt);
int m=(l+r)>>;
if(L<=m)update(L,R,c,ls);
if(R>m)update(L,R,c,rs);
tr[rt]=tr[rt<<]|tr[rt<<|];
} int pop(int x,int l=,int r=n,int rt=)
{
if(l==r){tr[rt]=;return l;}
pd(rt);
int ans,m=(l+r)>>;
if(tr[rt<<|]&x)ans=pop(x,rs);
else ans=pop(x,ls);
tr[rt]=tr[rt<<]|tr[rt<<|];
return ans;
}
int main(){
while(scanf("%d",&n),n)
{
printf("Case #%d:\n",ic++);
mst(tr,),mst(lazy,);
F(i,,n)
{
scanf("%s",op);
if(op[]=='p'&&op[]=='u')
{
scanf("%s%d",x,dt+i);
if(x[]=='A')update(i,i,);else update(i,i,);
}else if(op[]=='p')
{
scanf("%s",x);
if(x[]=='A')now=pop();else now=pop();
printf("%d\n",dt[now]);
}else
{
scanf("%s%s",x,y);
if(x[]=='A')update(,i,);else update(,i,);
}
}
}
return ;
}
#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef pair<int,int>P; const int N=5e4+;
int eda,edb,edc,n,tp,ic=,c[N];
char op[],x[],y[];
P a[N],b[N]; int main()
{
while(scanf("%d",&n),n)
{
printf("Case #%d:\n",ic++);
eda=edb=edc=;
F(i,,n)
{
scanf("%s",op);
if(op[]=='p'&&op[]=='u')
{
scanf("%s%d",x,&tp);
if(x[]=='A')a[++eda].first=tp,a[eda].second=i;
else b[++edb].first=tp,b[edb].second=i;
}else if(op[]=='p')
{
scanf("%s",x);
if(x[]=='A')
{
if(eda)printf("%d\n",a[eda--].first);
else printf("%d\n",c[edc--]);
}else
{
if(edb)printf("%d\n",b[edb--].first);
else printf("%d\n",c[edc--]);
}
}else
{
scanf("%s%s",x,y);
for(int ii=,jj=;ii<=eda||jj<=edb;)
{
if(ii<=eda&&jj<=edb)
{
if(a[ii].second<b[jj].second)c[++edc]=a[ii].first,ii++;
else c[++edc]=b[jj].first,jj++;
}else if(ii<=eda)c[++edc]=a[ii].first,ii++;
else if(jj<=edb)c[++edc]=b[jj].first,jj++;
}
eda=,edb=;
}
} }
return ;
}
hdu_5818_Joint Stacks(线段树模拟)的更多相关文章
- 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流
昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...
- 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)
题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树. 开始和队友 ...
- POJ-2886 Who Gets the Most Candies?(线段树+模拟)
题目大意:n个小孩按顺时针站成一圈,每次会有一个小孩出队(第一个出队的小孩已知),在他出队时会指定下一个出队的小孩,直到所有的小孩全部出队游戏结束.第p个出队的小孩会得到f(p)个糖果,f(p)为p的 ...
- 主席树/线段树模拟归并排序+二分答案(好题)——hdu多校第4场08
用主席树写起来跑的快一点,而且也很傻比,二分答案,即二分那个半径就行 主席树求的是区间<=k的个数 #include<bits/stdc++.h> using namespace s ...
- Luogu P4246 [SHOI2008]堵塞的交通(线段树+模拟)
P4246 [SHOI2008]堵塞的交通 题意 题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个\(2\)行\(C\)列的矩形 ...
- BZOJ1493 NOI2007 项链工厂 线段树模拟
提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...
- hdu4942线段树模拟rotate操作+中序遍历 回头再做
很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559 自己的代码不知道哪里出了点问题 /* rotate操作不会改 ...
- [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)
https://www.cnblogs.com/DaD3zZ-Beyonder/p/5634149.html k可重区间集问题有两种建图方式,可能这一种才可以被线段树优化. 换个角度看,这也是一个类似 ...
- poj 2828 buy Tickets 用线段树模拟带插入的队列
Buy Tickets Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2 ...
随机推荐
- Ubuntu14.04安装wineqq国际版出现无法输入中文的解决方法
执行命令:sudo vim /usr/bin/wine-qqintl 将"export LANG=zh_CN.utf8"改为"export LANG=en_US.utf8 ...
- hdu1722
链接 一份切成q份需要q刀,切成p份需要p刀:切的部分总会有重复,即gcd(p,q),减去重复部分就是要切的刀数 #include<stdio.h> int gcd(int n,int m ...
- iScroll 下 a 标签失效
遇到个莫名其妙的问题,iScroll 下的 a 标签点击没有反应了,不管怎么调整 z-index 都无效果,很是无语. 查找半天后找到解决方法: $(function(){ new IScroll(' ...
- Java错误提示is not an enclosing class
今天脑袋晕乎乎的,犯了个低级错误,好半天才反应过来 一直提示:is not an enclosing class 我居然把 RegisterActivity.class 写成了 RegisterAct ...
- 学习笔记_ADB常用指令
ADB 查看连接到计算机的Android设备或模拟器 adb devices 说明: 正常显示状态应该是IP:Port State. State=device说明设备已经连接到计算机, State=o ...
- 一些Android经验
1.如果在调试Android程序中,你非常确定你的代码是没有问题的,比如在跟Server交互时候,抓包软件抓到的包是正常的,但是在解析数据时候有问题, 你可以试着换个Android设备看看,模拟器换成 ...
- [SQL基础教程] 1-5 表的删除和更新
[SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...
- <密码的实现>输入密码的时候,显示“*”,而不是显示输入内容
一开始还以为用C语言和C++不能实现输入密码的时候显示出“*”而不显示输入的内容呢!没想到偶然的机会试出了用while循环结构可以实现.以下是我整理的C语言和C++的代码,供初学者参考. 这是C语言实 ...
- mx51的三个framebuffer,mxc_ipuv3_fb.c分析
转载:http://blog.csdn.net/jack_a8/article/details/43309169 mx51支持三个framebuffer:fb0, fb1, fb2 /dev/grap ...
- rebase
/BASE (Base Address) https://msdn.microsoft.com/en-us/library/f7f5138s.aspx Need for Rebasing a DLL( ...