题面

传送门

题解

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

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

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

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

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

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

  1. //minamoto
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define inline __inline__ __attribute__((always_inline))
  5. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  6. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  7. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  8. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  9. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  10. using namespace std;
  11. char buf[1<<21],*p1=buf,*p2=buf;
  12. inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
  13. int read(){
  14. R int res,f=1;R char ch;
  15. while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
  16. for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
  17. return res*f;
  18. }
  19. char sr[1<<21],z[20];int K=-1,Z=0;
  20. inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
  21. void print(R int x){
  22. if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
  23. while(z[++Z]=x%10+48,x/=10);
  24. while(sr[++K]=z[Z],--Z);sr[++K]='\n';
  25. }
  26. inline char getop(){R char ch;while((ch=getc())>'Z'||ch<'A');return ch;}
  27. unsigned int aaa=19260817;
  28. inline unsigned int rd(){aaa^=aaa>>15,aaa+=aaa<<12,aaa^=aaa>>3;return aaa;}
  29. const int N=5e5+5;
  30. struct node;typedef node* ptr;
  31. struct node{
  32. ptr lc,rc;int v,sz;unsigned int pr;
  33. inline ptr init(R int val){return v=val,sz=1,pr=rd(),this;}
  34. inline ptr upd(){return sz=lc->sz+rc->sz+1,this;}
  35. }e[N],*pp=e,*pl,*pr;map<int,ptr>rt;
  36. inline ptr newnode(R int v){return ++pp,pp->lc=pp->rc=e,pp->init(v);}
  37. void split(ptr p,int k,ptr &s,ptr &t){
  38. if(p==e)return s=t=e,void();
  39. if(p->v<=k)s=p,split(p->rc,k,p->rc,t);
  40. else t=p,split(p->lc,k,s,p->lc);
  41. p->upd();
  42. }
  43. ptr merge(ptr s,ptr t){
  44. if(s==e)return t;if(t==e)return s;
  45. if(s->pr<t->pr)return s->rc=merge(s->rc,t),s->upd();
  46. return t->lc=merge(s,t->lc),t->upd();
  47. }
  48. int n,m,lasans,a[N];
  49. struct zz{
  50. int l,r;mutable int v;
  51. inline zz(R int li,R int ri=0,R int vi=0):l(li),r(ri),v(vi){}
  52. inline bool operator <(const zz &b)const{return l<b.l;}
  53. };set<zz>s;typedef set<zz>::iterator IT;
  54. IT split(int pos){
  55. IT it=s.lower_bound(zz(pos));
  56. if(it!=s.end()&&it->l==pos)return it;
  57. --it;int l=it->l,r=it->r,v=it->v;
  58. s.erase(it),s.insert(zz(l,pos-1,v));
  59. return s.insert(zz(pos,r,v)).first;
  60. }
  61. void update(int l,int r,int v){
  62. IT itr=split(r+1),itl=split(l);
  63. s.erase(itl,itr),s.insert(zz(l,r,v));
  64. }
  65. int ask(int pos){
  66. IT it=s.lower_bound(zz(pos));
  67. if(it==s.end()||it->l!=pos)--it;
  68. return it->v;
  69. }
  70. int Kth(ptr p,int k){
  71. if(p->lc->sz==k-1)return p->v;
  72. if(p->lc->sz>=k)return Kth(p->lc,k);
  73. return Kth(p->rc,k-p->lc->sz-1);
  74. }
  75. int query(ptr &rt,int l,int r,int k){
  76. ptr s,t,p,q;
  77. split(rt,l-1,s,t),split(t,r,p,q);
  78. int now=p->sz>=k?Kth(p,k):0;
  79. return rt=merge(s,merge(p,q)),now;
  80. }
  81. void divide(ptr p,int k,int r,ptr &s,ptr &t){
  82. if(p==e)return s=t=e,void();
  83. if(p->lc->sz+k==p->v&&p->v<=r)s=p,divide(p->rc,k+p->lc->sz+1,r,p->rc,t);
  84. else t=p,divide(p->lc,k,r,s,p->lc);
  85. p->upd();
  86. }
  87. int change(ptr &p,int k,int r){
  88. ptr s,t,f,g;int now;
  89. split(p,k-1,f,g),divide(g,k,r,s,t);
  90. now=Kth(s,s->sz),p=merge(f,t),pl=merge(pl,s);
  91. return now+1;
  92. }
  93. int main(){
  94. // freopen("gold1.in","r",stdin);
  95. n=read(),m=read(),lasans=0,e->lc=e->rc=e;
  96. fp(i,1,n){
  97. a[i]=read();if(rt[a[i]]==NULL)rt[a[i]]=e;
  98. rt[a[i]]=merge(rt[a[i]],newnode(i));
  99. s.insert(zz(i,i,a[i]));
  100. }
  101. for(int op,l,r,v,k,tl,tr,c;m;--m){
  102. op=getop(),l=read()^lasans,r=read()^lasans;
  103. if(op=='M'){
  104. v=read()^lasans,tl=l,tr=r;if(rt[v]==NULL)rt[v]=e;
  105. split(rt[v],l-1,pl,pr),split(pr,r,rt[v],pr);
  106. while(tl<=tr)c=ask(tl),tl=change(rt[c],tl,r);
  107. rt[v]=merge(pl,pr);
  108. update(l,r,v);
  109. }else{
  110. k=read()^lasans,v=read()^lasans;if(rt[v]==NULL)rt[v]=e;
  111. print(lasans=query(rt[v],l,r,k));
  112. }
  113. }
  114. return Ot(),0;
  115. }

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. java中文乱码问题的处理方式

    URL访问java时. 注意: URL: 编码二次 URLEncoder.encode(URLEncoder.encode(searchKey, "utf-8"),"ut ...

  2. Bad Luck Island-CodeForce(dp)

    链接:http://codeforces.com/problemset/problem/540/D 题目大意: 这个岛上有三种生物   r石头  s剪刀 p布 求最后只剩一种生物的概率 用dp[i][ ...

  3. 选择器的使用(nth-of-type和nth-last-of-type选择器)

    <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...

  4. SAS编程基础 - 数据获取与数据集操作(1)

    1. 数据来源 SAS数据来源主要有两种:一是通过input语句创建,另外一种方式是通过外部数据文件获取. 1.1 libname 1.2 odbc 1.3 passthrough 1.4 impor ...

  5. Mysql中错误日志、binlog日志、查询日志、慢查询日志简单介绍

    前言 数据库的日志是帮助数据库管理员,追踪分析数据库以前发生的各种事件的有力根据.mysql中提供了错误日志.binlog日志(二进制日志).查处日志.慢查询日志.在此,我力求解决下面问题:各个日志的 ...

  6. JButton点击事件

    JButton点击事件: 以前都是搞一个JFrame,放个JButton,然后用鼠标点击: 忽然之间: import javax.swing.JButton; public class Page06 ...

  7. 『NSOperation、NSOperationQueue』详解

    1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...

  8. JavaScript图片裁剪

    1.jquery 图片裁剪库选择 Jcrop:http://deepliquid.com/content/Jcrop.html imgareaselect:http://odyniec.net/pro ...

  9. 公钥加密,摘要算法MD5,SSH相关概念

    1.公钥加密,又叫非对称加密,一般指的是用一组密钥来保证通信的安全.(公钥,私钥)成对存在且惟一,典型的公钥算法有 RSA(计算出的是1024位,128字节),顺便提一下与公钥加密算法相对应的就是传统 ...

  10. java8-接口变化-默认方法-静态方法

    Java 8中允许接口中包含具有具体实现的方法,该方法称为 “默认方法”,默认方法使用 default 关键字修饰. default String getName(){ return "哈哈 ...