思路:

RT

可以看VFK的题解

我写了半天拍了半天...

不过是$nlog^2n$的

要写垃圾回收的

线段树 如果某个节点的sum是0  也可以free掉

//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=;
int root[],n,q,xx,yy,zz,Root,ans;
struct Segment_Tree{
int rubbish[],top,tree[],lson[],rson[];
int get_rubbish(){if(rubbish[top])return rubbish[top--];return top--;}
void insert(int l,int r,int &pos,int num,int wei){
if(!pos)pos=get_rubbish();
if(l==r){tree[pos]+=wei;return;}
int mid=(l+r)>>;
if(mid>=num)insert(l,mid,lson[pos],num,wei);
else insert(mid+,r,rson[pos],num,wei);
tree[pos]=tree[lson[pos]]+tree[rson[pos]];
if(!tree[lson[pos]]&&lson[pos])rubbish[++top]=lson[pos],lson[pos]=;
if(!tree[rson[pos]]&&rson[pos])rubbish[++top]=rson[pos],rson[pos]=;
}
void merge(int x,int y,int &k){
if(!k)k=get_rubbish();
tree[k]=tree[x]+tree[y];
if(lson[x]||lson[y])merge(lson[x],lson[y],lson[k]);
if(rson[x]||rson[y])merge(rson[x],rson[y],rson[k]);
}
void dfs(int l,int r,int x){
int mid=(l+r)>>;
if(lson[x])dfs(l,mid,lson[x]),rubbish[++top]=lson[x];
if(rson[x])dfs(mid+,r,rson[x]),rubbish[++top]=rson[x];
lson[x]=rson[x]=tree[x]=;
}
}segtree;
int top1,top2,stk1[],stk2[];
struct SC_TREE{
int top,rubbish[],lson[],rson[],wei[],size[];
int get_rubbish(){return rubbish[top--];}
void build(int &k,int l,int r){
if(l>r)return;
if(!k)k=get_rubbish();
int mid=(l+r)>>;wei[k]=stk2[mid];
if(l==r){segtree.insert(,N,root[k],stk2[l],),size[k]=;return;}
build(lson[k],l,mid-),build(rson[k],mid+,r);
segtree.merge(root[lson[k]],root[rson[k]],root[k]);
segtree.insert(,N,root[k],stk2[mid],);
size[k]=size[lson[k]]+size[rson[k]]+;
}
void init(){for(int i=;i<=;i++)rubbish[i]=-i+;top=;segtree.top=,build(Root,,n);}
int find_wei(int x,int sz){
if(size[lson[x]]+==sz)return wei[x];
else if(size[lson[x]]>=sz)return find_wei(lson[x],sz);
else return find_wei(rson[x],sz-size[lson[x]]-);
}
void change(int x,int sz,int w,int last_w){
segtree.insert(,N,root[x],last_w,-);
segtree.insert(,N,root[x],w,);
if(size[lson[x]]+==sz){wei[x]=w;return;}
else if(size[lson[x]]>=sz)change(lson[x],sz,w,last_w);
else change(rson[x],sz-size[lson[x]]-,w,last_w);
}
void query(int l,int r,int x){
int L=size[lson[x]],R=size[x];
if(l==&&R==r){stk1[++top1]=root[x];return;}
if(l<=L+&&r>=L+)stk2[++top2]=wei[x];
if(r<=L)query(l,r,lson[x]);
else if(l>L+)query(l-L-,r-L-,rson[x]);
else{
if(l<=L)query(l,L,lson[x]);
if(r>L+)query(,r-L-,rson[x]);
}
}
int Query(int l,int r,int kth){
top1=top2=;query(l,r,Root);
int L=,R=N,ans=,M,temp;
while(L<R){
M=(L+R)>>;temp=;
for(int i=;i<=top1;i++)temp+=segtree.tree[segtree.lson[stk1[i]]];
for(int i=;i<=top2;i++)if(stk2[i]<=M&&stk2[i]>=L)temp++;
if(temp>kth){for(int i=;i<=top1;i++)stk1[i]=segtree.lson[stk1[i]];R=M;}
else {for(int i=;i<=top1;i++)stk1[i]=segtree.rson[stk1[i]];L=M+;kth-=temp;}
}return L;
}
void dfs(int x){
segtree.dfs(,N,root[x]);root[x]=;
if(lson[x])dfs(lson[x]),rubbish[++top]=lson[x];
stk2[++top2]=wei[x];
if(rson[x])dfs(rson[x]),rubbish[++top]=rson[x];
lson[x]=rson[x]=wei[x]=size[x]=;
}
int rebuild(int sz,int &x){top2=,dfs(x),build(x,,sz);}
bool insert(int &x,int sz,int w){
if(!x){x=get_rubbish();segtree.insert(,N,root[x],w,);size[x]=;wei[x]=w;return ;}
segtree.insert(,N,root[x],w,),size[x]++;
if(size[lson[x]]>=sz){if(insert(lson[x],sz,w))rebuild(size[lson[x]],lson[x]);}
else if(insert(rson[x],sz-size[lson[x]]-,w))rebuild(size[rson[x]],rson[x]);
if(max(size[lson[x]],size[rson[x]])>0.666*size[x])return ;return ;
}
}SC_Tree;
int read(){
int x=;char p=getchar();
while(p<''||p>'')p=getchar();
while(p>=''&&p<='')x=x*+p-'',p=getchar();
return x;
}
char readchar(){char p=getchar();while(p!='Q'&&p!='M'&&p!='I')p=getchar();return p;}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&stk2[i]);
SC_Tree.init();
scanf("%d",&q);
while(q--){
char op=readchar();xx=read()^ans,yy=read()^ans;
if(op=='Q')zz=read()^ans,printf("%d\n",ans=SC_Tree.Query(xx,yy,zz-));
else if(op=='M')SC_Tree.change(Root,xx,yy,SC_Tree.find_wei(Root,xx));
else SC_Tree.insert(Root,xx-,yy);
}
}

BZOJ 3065 替罪羊树+动态开节点线段树的更多相关文章

  1. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  2. 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)

    题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...

  3. BZOJ4636: 蒟蒻的数列(动态开节点线段树)

    题意 题目链接 Sol 直接上动态开节点线段树 因为只有一次询问,所以中途不需要下传标记 #include<bits/stdc++.h> #define LL long long usin ...

  4. 洛谷P3960 列队(动态开节点线段树)

    题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...

  5. Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

    思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 els ...

  6. 洛谷P4632 [APIO2018] New Home 新家(动态开节点线段树 二分答案 扫描线 set)

    题意 题目链接 Sol 这题没有想象中的那么难,但也绝对不简单. 首先把所有的询问离线,按照出现的顺序.维护时间轴来处理每个询问 对于每个询问\((x_i, y_i)\),可以二分答案\(mid\). ...

  7. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

  8. BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树

    题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...

  9. BZOJ 3531: [Sdoi2014]旅行 (树剖+动态开点线段树)

    对于每种信仰维护一棵动态开点线段树就行了- #include <cstdio> #include <cctype> #include <cstring> #incl ...

随机推荐

  1. Deutsch lernen (06)

    1. das Verzeichnis,-se 表格:名单,目录 Die Daten sind in einem Verzeichnis enthalten. (包括,含有) 2. enthalten  ...

  2. IronPython中共享的C#基类如何向下转型

    在项目中,我们使用IronPython来定义工作流脚本来以应对科研多变的需求.项目使用的主要语言仍然是C#,使用C#封装了各种基础服务与基础设施.Python脚本只使用C#提供的服务,或者说只定义了逻 ...

  3. 论 fmap、fmap fmap、与 fmap fmap fmap

    https://blog.csdn.net/sinat_25226993/article/details/44415803

  4. 【转】虚拟化(五):vsphere高可用群集与容错

    vsphere高级功能需要vcenter server和共享存储的支持才能实现.vsphere的高级功能有 vmotion.storage vmotion.vsphere HA.vsphere DRS ...

  5. 【剑指Offer】50、数组中重复的数字

      题目描述:   在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果 ...

  6. 【剑指Offer】8、跳台阶

      题目描述:   一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果).   解题思路:   首先考虑最简单的情况,如果只有1级台阶, ...

  7. 重新学习html和css

    当初学习前端的时候,属于快速入门那种,没有好好深入学习html和css.如今,在空闲时间重新拿起基础书学习,都会写到一些新的知识. 1.css实现圆角.渐变功能.使用border-radius以及li ...

  8. python orm框架-----SQLALchemy-查询篇

    似乎ORM最难设计的部分是查询.特别是面向对象的查询,今天学习SQLAlchemy,发现SQLAlchemy的查询语法竟如此灵活,惊叹其如此强大的表达能力的同时也对Python也有了更深的认识.下面看 ...

  9. MS SQL 迁移数据库文件

    MS SQL 数据库迁移文件,这里说的不是将数据库迁移到另外一台服务器,只是在服务器不同磁盘目录内做迁移.移动数据库文件的情况大致有下面一些: 1: 事先没有规划好,数据库文件或日志文件增长过快,导致 ...

  10. 转载 - Pinyin4j的基本用法

    原文:http://blog.csdn.net/pathuang68/article/details/6692882 1.     简单介绍 有时候,需要将汉字编程对应的拼音,以方便数据的处理.比如在 ...