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 ...
随机推荐
- 我是这样使用template.js来异步渲染数据的
总监的代码用的是define+module.exports,为了效率先没去了解那一块,在github上找了一款功能单一的template.js来使用 https://github.com/yanhai ...
- 最全js 放大镜效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- MATLAB中的微积分运算(数值&符号)
显然这个函数是单词differential(微分)的简写,用于计算微分.实际上准确来说计算的是差商. 如果输入一个长度为n的一维向量,则该函数将会返回长度为n-1的向量,向量的值是原向量相邻元素的差, ...
- struts2.0中struts.xml配置文件详解
先来展示一个配置文件 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration ...
- Android抽屉效果 DrawerLayout 入门经验总结
今天试了试这个抽屉布局的效果,结果很崩溃无语 网上很多资料都千篇一律,感觉都有问题,下面总结下几点经验: 先上个效果图: 1. layout 布局文件中怎么写: <android.suppor ...
- AngularJS中如何对Controller与Service进行分层设计与编码
初学者的Controller 在我们当接触NG后,如需要通过访问远程的API获取一系列的数据进行显示,通常我的Controller代码会写成下面的样子: angular.module('demo') ...
- Junit4单元测试之高级用法
Junit单元测试框架是Java程序开发必备的测试利器,现在最常用的就是Junit4了,在Junit4中所有的测试用例都使用了注解的形式,这比Junit3更加灵活与方便.之前在公司的关于单元测试的培训 ...
- Linux 下搭建jsp服务器(配置jsp开发环境)
Linux 做为服务器的高效一直时为人所熟知的了,在linux 上搭建各种各样的服务器和开发环境也时学计算机的人常做的.以下时最近在linux配置jsp服务器的全过程,包含一些基本步骤和排错过程: 1 ...
- oc 导航栏跳转指定界面
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIn ...
- Flexslider图片轮播、文字图片相结合滑动切换效果
Flexslider是一款基于的jQuery内容滚动插件.它能让你轻松的创建内容滚动的效果,具有非常高的可定制性.开发者可以使用Flexslider轻松创建各种图片轮播效果.焦点图效果.图文混排滚动效 ...