题目链接: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(线段树模拟)的更多相关文章

  1. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流

    昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...

  2. 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)

    题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树.  开始和队友 ...

  3. POJ-2886 Who Gets the Most Candies?(线段树+模拟)

    题目大意:n个小孩按顺时针站成一圈,每次会有一个小孩出队(第一个出队的小孩已知),在他出队时会指定下一个出队的小孩,直到所有的小孩全部出队游戏结束.第p个出队的小孩会得到f(p)个糖果,f(p)为p的 ...

  4. 主席树/线段树模拟归并排序+二分答案(好题)——hdu多校第4场08

    用主席树写起来跑的快一点,而且也很傻比,二分答案,即二分那个半径就行 主席树求的是区间<=k的个数 #include<bits/stdc++.h> using namespace s ...

  5. Luogu P4246 [SHOI2008]堵塞的交通(线段树+模拟)

    P4246 [SHOI2008]堵塞的交通 题意 题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个\(2\)行\(C\)列的矩形 ...

  6. BZOJ1493 NOI2007 项链工厂 线段树模拟

    提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...

  7. hdu4942线段树模拟rotate操作+中序遍历 回头再做

    很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559 自己的代码不知道哪里出了点问题 /* rotate操作不会改 ...

  8. [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)

    https://www.cnblogs.com/DaD3zZ-Beyonder/p/5634149.html k可重区间集问题有两种建图方式,可能这一种才可以被线段树优化. 换个角度看,这也是一个类似 ...

  9. poj 2828 buy Tickets 用线段树模拟带插入的队列

    Buy Tickets Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2 ...

随机推荐

  1. vue+webpack构建项目

    概述 -- 项目中会用到的插件 vue-router vue-resource 打包工具 webpack 依赖环境 node.js start 安装vue开发的模板 # 全局安装 vue-cli $ ...

  2. Amdahl's Law

    Amdahl's Law 程序可能的加速比取决于可以被并行化的部分. 如果没有可以被并行化的部分,则P=0,speedup=1,no speedup. 如果全部可以被并行化,P=1,speedup i ...

  3. delphi 输入文件相对路径的更改,更改成用户的

  4. metrics实践 (metrics-spring)

    这里主要介绍metrics与spring集成的使用方式. 1  添加maven依赖 <dependency> <groupId>com.ryantenney.metrics&l ...

  5. hdu1033

    #include<stdio.h> #include<string.h> const int MAXN=200; char str[MAXN]; int main() { in ...

  6. mac 搭建node 开发环境记录

    安装homebrew: enter 键 后 输入电脑密码 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/i ...

  7. spring-事务实现原理

    spring事务的实现原理:aop. aop的两种实现方式: 1.动态代理: 事务方法与调用方法不能在同一个类中,否则事务不生效.解决方案,自己注入自己(实质注入的是代理类). 实现方式:jdk动态代 ...

  8. HDU 1329 Hanoi Tower Troubles Again!(乱搞)

    Hanoi Tower Troubles Again! Problem Description People stopped moving discs from peg to peg after th ...

  9. Chapter 20_1 table库

    table库是由一些辅助函数构成,把table作为数组来操作,所有的函数都忽略传入参数的那张表中的非数字键. 无论如何,若一个操作需要取表的长度,这个表必须是一个真序列,或是拥有__len元方法. 提 ...

  10. Dreamweaver层使用八定律

    当然,这些并非真正的定律,而只是一些有益的忠告,使你免陷于使用层时可能的困顿中.原来有九条定律的,我们精简掉一条,还有下面的八条: 1. 如果你要嵌套层,决不要使用多重父层,应共享一个共同的单一父层. ...