前几周考试的时候考了,正解给的是线段树套堆(专门卡这个做法的空间). 
 
这里先写一下可持久化线段树的做法(应该是官方正解吧). 
 
搞两个线段树,一个维护的是权值(查询答案时调用的).
另一个维护的是每个下标在每一个操作时刻被哪个操作在顶上覆盖着(这是一个可持久化线段树).
这样做有什么好处呢 ?
我们举个例子:
 
 假设这是一个 $l$ 位置的栈.
 当前要进行弹栈操作.
 在 $rt[i-1]$ 中查询,能查到 $o$ (最新一次压栈).
 我们知道,$o$ 压入的数是要被弹出去的,取而代之的是 $oo$ 所压入的数.
 
 我们在 $rt[o-1]$ 中再查询一次就可以查到 $oo$ 了.
 对应的,只需在第一颗维护权值的线段树中把对应点赋值为 $oo$ 所对应的权值即可.
 在可持久化线段树中的操作是新建一个 $i$ 版本,与 $i-1$ 唯一不同就是 $o->oo$.
 区间压栈在两颗线段树中对应的都是区间赋值. 
#include<bits/stdc++.h>
#define maxn 500005
using namespace std;
int n,Q,ty,lastans=0;
int rt[maxn], tim[maxn], lp[maxn], tp[maxn];
void setIO(string s)
{
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
namespace tree1
{
#define lson ( x<<1)
#define rson ( (x<<1)|1)
int sumv[500005<<2],lazy[500005<<2];
void mark(int l,int r,int x,int k)
{
sumv[x]=(r-l+1)*k;
lazy[x]=k;
}
void pushup(int x)
{
sumv[x]=sumv[lson]+sumv[rson];
}
void pushdown(int l,int r,int x)
{
if(!lazy[x]) return;
int mid=(l+r)>>1;
if(mid >= l) mark(l, mid, lson, lazy[x]);
if(r > mid) mark(mid + 1, r, rson, lazy[x]);
lazy[x]=0;
}
void update(int l,int r,int x,int L,int R,int k)
{
if(l>=L&&r<=R)
{
mark(l,r,x,k);
return;
}
pushdown(l,r,x);
int mid=(l+r)>>1;
if(L<=mid) update(l,mid,lson,L,R,k);
if(R>mid) update(mid+1,r,rson,L,R,k);
pushup(x);
}
int query(int l,int r,int x,int L,int R)
{
if(l>=L&&r<=R) return sumv[x];
pushdown(l, r, x);
int mid=(l+r)>>1, tmp=0;
if(L<=mid) tmp+=query(l,mid,lson,L,R);
if(R>mid) tmp+=query(mid+1,r,rson,L,R);
return tmp;
}
#undef lson
#undef rson
}; namespace tree2
{
int tot=0;
int tag[maxn*75],value[maxn*75];
int lson[maxn*75],rson[maxn*75];
void mark(int x,int delta)
{
value[x]=tag[x]=delta;
return;
}
void pushdown(int l,int r,int x)
{
if(!tag[x]) return;
int mid=(l+r)>>1;
if(mid>=l && !lson[x]) lson[x]=++tot;
if(r > mid && !rson[x]) rson[x]=++tot;
if(lson[x]) mark(lson[x], tag[x]);
if(rson[x]) mark(rson[x], tag[x]);
tag[x]=0;
}
void add(int &k,int kk,int l,int r,int L,int R,int delta)
{
tag[k=++tot]=0;
if(l>=L&&r<=R)
{
mark(k, delta);
return;
}
int mid=(l+r)>>1;
pushdown(l,r,kk);
lson[k]=lson[kk], rson[k]=rson[kk];
if(L <= mid) add(lson[k], lson[kk], l, mid, L, R, delta);
if(R > mid) add(rson[k], rson[kk], mid + 1, r, L, R, delta);
}
int query(int l,int r,int k,int pos)
{
if(!k || l == r) return value[k];
pushdown(l,r,k);
int mid=(l+r)>>1;
if(pos<=mid)
return query(l,mid,lson[k], pos);
else
return query(mid+1,r,rson[k],pos);
}
};
int main()
{
// setIO("input");
scanf("%d%d%d",&n,&Q,&ty);
int opt,l,r,dd;
for(int i=1;i<=Q;++i)
{
scanf("%d",&opt);
switch(opt)
{
case 1 :
{
scanf("%d%d",&l,&r);
l=(l+lastans*ty)%n+1;
r=(r+lastans*ty)%n+1;
if(l>r) swap(l,r);
lastans=tree1::query(1,n,1,l,r);
printf("%d\n",lastans);
rt[i]=rt[i-1];
break;
}
case 2 :
{
scanf("%d",&l);
l=(l+lastans*ty)%n+1;
int o = tree2::query(1, n, rt[i-1],l); //查询修改的 l 的修改操作.
if(!o) rt[i]=rt[i-1];
else
{
int oo = tree2::query(1,n,rt[o-1],l); // 上一次操作
tree1::update(1,n,1,l,l,tp[oo]); //
tree2::add(rt[i], rt[i-1], 1, n, l,l,oo);
}
break;
}
case 3 :
{
scanf("%d%d%d",&l,&r,&dd);
l=(l+lastans*ty)%n+1;
r=(r+lastans*ty)%n+1;
if(l>r) swap(l,r);
tp[i]=dd;
tree1::update(1,n,1,l,r,dd);
tree2::add(rt[i],rt[i-1],1,n,l,r,i);
break;
}
}
}
return 0;
}

  

最新文章

  1. 在项目中同时使用Objective-C和Swift
  2. jquery mobile 问问多多
  3. 【转】高效Java编程工具集锦
  4. Loadrunner代理录制设置
  5. unity3D游戏-WorldFight
  6. 【运维工具】Git代码发布系统
  7. lua 位运算
  8. python web编程-web客户端编程
  9. 解决阿里云SLB无法添加https证书的问题
  10. C语言接口与实现实例
  11. first root
  12. LR性能测试脚本增强与调试
  13. WP8 学习 在APP.XAML中加入Resources
  14. 软件工程个人作业4(课堂练习&amp;&amp;课堂作业)
  15. 项目中重新引用WCF报错
  16. c++中string类的详解
  17. php引入公用部分html出现了一行空白(原创)
  18. 用VBA读取Excel表格输出到格式化的xml文件中
  19. java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListene解决办法
  20. CDH集成Kafka,两种方式:离线、在线

热门文章

  1. volley基本使用方法
  2. php file_get_contents遇到https的处理办法
  3. (5)QlikView中的RowNo()函数
  4. 小米手机 js 脚本取src为空的适配问题
  5. mongodb数据库的启动和停止
  6. Apache OFBIZ高速上手(二)--MVC框架
  7. Android View的onTouch和onClick和onLongClick事件
  8. Mac safari&#160;下iframe的hash取不到BUG
  9. UIDynamicBehavior的简单使用:接球小游戏
  10. PCB MS SQL 将字符串分割为表变量(表值函数)