题面

传送门

题解

好吧我是不太会复杂度分析……

我们对于每种颜色用一个数据结构维护(比方说线段树或者平衡树,代码里写的平衡树),那么区间询问很容易就可以解决了

所以现在的问题是区间修改,如果区间颜色相等直接\(O(\log n)\)修改就好了,否则的话,一个很暴力的思路是把区间分成若干段颜色相等的部分,每一个部分都直接\(O(\log n)\)修改

乍看这样是\(gg\)的,但是我们仔细观察一下,每一次修改的时候只有相邻两段颜色不同的时候会贡献\(O(\log n)\)的复杂度,而初始时段数是\(O(n)\)的,每一次修改的时候增加的段数是常数,所以总的复杂度是\(O((n+m)\log n)\)

ps:因为修改的时候要暴力跳区间需要资瓷查询某个点的颜色所以写了个珂朵莉树

pps:虽然说起来很简单但是调起来非常麻烦……

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
inline char getop(){R char ch;while((ch=getc())>'Z'||ch<'A');return ch;}
unsigned int aaa=19260817;
inline unsigned int rd(){aaa^=aaa>>15,aaa+=aaa<<12,aaa^=aaa>>3;return aaa;}
const int N=5e5+5;
struct node;typedef node* ptr;
struct node{
ptr lc,rc;int v,sz;unsigned int pr;
inline ptr init(R int val){return v=val,sz=1,pr=rd(),this;}
inline ptr upd(){return sz=lc->sz+rc->sz+1,this;}
}e[N],*pp=e,*pl,*pr;map<int,ptr>rt;
inline ptr newnode(R int v){return ++pp,pp->lc=pp->rc=e,pp->init(v);}
void split(ptr p,int k,ptr &s,ptr &t){
if(p==e)return s=t=e,void();
if(p->v<=k)s=p,split(p->rc,k,p->rc,t);
else t=p,split(p->lc,k,s,p->lc);
p->upd();
}
ptr merge(ptr s,ptr t){
if(s==e)return t;if(t==e)return s;
if(s->pr<t->pr)return s->rc=merge(s->rc,t),s->upd();
return t->lc=merge(s,t->lc),t->upd();
}
int n,m,lasans,a[N];
struct zz{
int l,r;mutable int v;
inline zz(R int li,R int ri=0,R int vi=0):l(li),r(ri),v(vi){}
inline bool operator <(const zz &b)const{return l<b.l;}
};set<zz>s;typedef set<zz>::iterator IT;
IT split(int pos){
IT it=s.lower_bound(zz(pos));
if(it!=s.end()&&it->l==pos)return it;
--it;int l=it->l,r=it->r,v=it->v;
s.erase(it),s.insert(zz(l,pos-1,v));
return s.insert(zz(pos,r,v)).first;
}
void update(int l,int r,int v){
IT itr=split(r+1),itl=split(l);
s.erase(itl,itr),s.insert(zz(l,r,v));
}
int ask(int pos){
IT it=s.lower_bound(zz(pos));
if(it==s.end()||it->l!=pos)--it;
return it->v;
}
int Kth(ptr p,int k){
if(p->lc->sz==k-1)return p->v;
if(p->lc->sz>=k)return Kth(p->lc,k);
return Kth(p->rc,k-p->lc->sz-1);
}
int query(ptr &rt,int l,int r,int k){
ptr s,t,p,q;
split(rt,l-1,s,t),split(t,r,p,q);
int now=p->sz>=k?Kth(p,k):0;
return rt=merge(s,merge(p,q)),now;
}
void divide(ptr p,int k,int r,ptr &s,ptr &t){
if(p==e)return s=t=e,void();
if(p->lc->sz+k==p->v&&p->v<=r)s=p,divide(p->rc,k+p->lc->sz+1,r,p->rc,t);
else t=p,divide(p->lc,k,r,s,p->lc);
p->upd();
}
int change(ptr &p,int k,int r){
ptr s,t,f,g;int now;
split(p,k-1,f,g),divide(g,k,r,s,t);
now=Kth(s,s->sz),p=merge(f,t),pl=merge(pl,s);
return now+1;
}
int main(){
// freopen("gold1.in","r",stdin);
n=read(),m=read(),lasans=0,e->lc=e->rc=e;
fp(i,1,n){
a[i]=read();if(rt[a[i]]==NULL)rt[a[i]]=e;
rt[a[i]]=merge(rt[a[i]],newnode(i));
s.insert(zz(i,i,a[i]));
}
for(int op,l,r,v,k,tl,tr,c;m;--m){
op=getop(),l=read()^lasans,r=read()^lasans;
if(op=='M'){
v=read()^lasans,tl=l,tr=r;if(rt[v]==NULL)rt[v]=e;
split(rt[v],l-1,pl,pr),split(pr,r,rt[v],pr);
while(tl<=tr)c=ask(tl),tl=change(rt[c],tl,r);
rt[v]=merge(pl,pr);
update(l,r,v);
}else{
k=read()^lasans,v=read()^lasans;if(rt[v]==NULL)rt[v]=e;
print(lasans=query(rt[v],l,r,k));
}
}
return Ot(),0;
}

LOJ#557. 「Antileaf's Round」你这衣服租来的吗(FHQ Treap+珂朵莉树)的更多相关文章

  1. LOJ #556. 「Antileaf's Round」咱们去烧菜吧

    好久没更博了 咕咕咕 现在多项式板子的常数巨大...周末好好卡波常吧.... LOJ #556 题意 给定$ m$种物品的出现次数$ B_i$以及大小$ A_i$ 求装满大小为$[1..n]$的背包的 ...

  2. 【刷题】LOJ 556 「Antileaf's Round」咱们去烧菜吧

    题目描述 你有 \(m\) 种物品,第 \(i\) 种物品的大小为 \(a_i\) ​,数量为 \(b_i\)​( \(b_i=0\) 表示有无限个). 你还有 \(n\) 个背包,体积分别为 \(1 ...

  3. loj558 「Antileaf's Round」我们的CPU遭到攻击

    考完了可以发题解了. 做法是link-cut tree维护子树信息,并不需要维护黑树白树那些的. 下面是一条重链: 如果4是根的话,那么在splay上是这样的: 在splay中,子树的信息都已经计算完 ...

  4. 「学习笔记」珂朵莉树 ODT

    珂朵莉树,也叫ODT(Old Driver Tree 老司机树) 从前有一天,珂朵莉出现了... 然后有一天,珂朵莉树出现了... 看看图片的地址 Codeforces可还行) 没错,珂朵莉树来自Co ...

  5. 「LOJ 556 Antileaf's Round」咱们去烧菜吧

    「LOJ 556 Antileaf's Round」咱们去烧菜吧 最近在看 jcvb 的生成函数课件,顺便切一切上面讲到的内容的板子题,这个题和课件上举例的背包计数基本一样. 解题思路 首先列出答案的 ...

  6. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  7. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  8. Loj #2321. 「清华集训 2017」无限之环

    Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...

  9. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

随机推荐

  1. HDU3032 nim博弈

    题目大意: 可以从某一堆中取任意个数,也可把一堆分成两个不为0的堆,直到某一方无法操作为输 因为是nim博弈,所以只要考虑一堆时候的sg值,把所有堆的sg值异或即可 很显然这里 0 是一个终止态 sg ...

  2. P1072 Hankson的趣味题

    #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #inclu ...

  3. android开发里跳过的坑——调用已安装视频播放器在有些机器上无效

    调用已安装视频播放器播放未修改之前的代码 private void startPlay(String fileName){ File file = new File(fileName); Intent ...

  4. codevs3164 质因数分解

    题目描述 Description (多数据)给出t个数,求出它的质因子个数. 数据没坑,难度降低. 输入描述 Input Description 第一行 t 之后t行 数据 输出描述 Output D ...

  5. POJ 1127_Jack Straws

    %: 对于二维向量p1=(x1,y1),p2=(x2,y2),定义内积p1⋅p2=x1x2+y1y2,外积p1×p2=x1y2−y1x2,则判断点q是否在线段p1−p2上: 先利用外积判断q是否在直线 ...

  6. 洛谷——P1044 栈

    P1044 栈——卡特兰数 题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈) ...

  7. Minimum Path Sum(DFS,DP)

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  8. LENOVO System x3850 X6

    http://appserver.lenovo.com.cn/Lenovo_Series_List.aspx?CategoryCode=A31B01

  9. how to read openstack code : wsgi

    要读懂本篇,你至少得写过一个python的web程序,并且把它部署到web服务器上过. 什么是wsgi 假设你写了一个python的web程序,并部署到了nginx上,那么一个http request ...

  10. nodejs参考文章

    http://www.cnblogs.com/lily1010/p/6683987.html https://manlili.github.io/2015/04/06/Node%E5%85%A5%E9 ...