解题思路:

很显然突破口就是字符集比较小,分块和线段树都能A

话说线段树时间是分块5倍啊

代码(线段树):

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define lll spc<<1
  5. #define rrr spc<<1|1
  6. struct int_26{
  7. int has[];
  8. void res(void)
  9. {
  10. memset(has,,sizeof(has));
  11. return ;
  12. }
  13. int_26 friend operator + (int_26 x,int_26 y)
  14. {
  15. int_26 ans;
  16. for(int i=;i<=;i++)
  17. ans.has[i]=x.has[i]+y.has[i];
  18. return ans;
  19. }
  20. }isr;
  21. struct trnt{
  22. int_26 val;
  23. int lzt;
  24. }tr[];
  25. int n,q;
  26. int ans[];
  27. char cmd[];
  28. void pushup(int spc)
  29. {
  30. tr[spc].val=tr[lll].val+tr[rrr].val;
  31. return ;
  32. }
  33. void pushdown(int spc,int l,int r)
  34. {
  35. if(tr[spc].lzt)
  36. {
  37. int mid=(l+r)>>;
  38. tr[lll].lzt=tr[spc].lzt;
  39. tr[rrr].lzt=tr[spc].lzt;
  40. tr[spc].lzt=;
  41. tr[lll].val.res();
  42. tr[rrr].val.res();
  43. tr[lll].val.has[tr[lll].lzt]=mid-l+;
  44. tr[rrr].val.has[tr[rrr].lzt]=r-mid;
  45. }
  46. return ;
  47. }
  48. void build(int spc,int l,int r)
  49. {
  50. if(l==r)
  51. {
  52. tr[spc].val.has[cmd[l]-'a'+]=;
  53. return ;
  54. }
  55. int mid=(l+r)>>;
  56. build(lll,l,mid);
  57. build(rrr,mid+,r);
  58. pushup(spc);
  59. return ;
  60. }
  61. void update(int l,int r,int ll,int rr,int spc,int v)
  62. {
  63. if(l>rr||ll>r)
  64. return ;
  65. if(ll<=l&&r<=rr)
  66. {
  67. tr[spc].val.res();
  68. tr[spc].val.has[v]=r-l+;
  69. tr[spc].lzt=v;
  70. return ;
  71. }
  72. int mid=(l+r)>>;
  73. pushdown(spc,l,r);
  74. update(l,mid,ll,rr,lll,v);
  75. update(mid+,r,ll,rr,rrr,v);
  76. pushup(spc);
  77. return ;
  78. }
  79. int_26 query(int l,int r,int ll,int rr,int spc)
  80. {
  81. if(l>rr||ll>r)
  82. return isr;
  83. if(ll<=l&&r<=rr)
  84. return tr[spc].val;
  85. int mid=(l+r)>>;
  86. pushdown(spc,l,r);
  87. return query(l,mid,ll,rr,lll)+query(mid+,r,ll,rr,rrr);
  88. }
  89. void S_pushdown(int l,int r,int spc)
  90. {
  91. if(l==r)
  92. {
  93. for(int i=;i<=;i++)
  94. if(tr[spc].val.has[i])
  95. {
  96. ans[l]=i;
  97. break;
  98. }
  99. return ;
  100. }
  101. int mid=(l+r)>>;
  102. pushdown(spc,l,r);
  103. S_pushdown(l,mid,lll);
  104. S_pushdown(mid+,r,rrr);
  105. return ;
  106. }
  107. int main()
  108. {
  109. scanf("%d%d",&n,&q);
  110. scanf("%s",cmd+);
  111. build(,,n);
  112. while(q--)
  113. {
  114. int l,r,op;
  115. scanf("%d%d%d",&l,&r,&op);
  116. if(l>r)
  117. std::swap(l,r);
  118. int_26 tmp=query(,n,l,r,);
  119. if(op)
  120. {
  121. int sta=l;
  122. for(int i=;i<=;i++)
  123. {
  124. if(!tmp.has[i])
  125. continue;
  126. update(,n,sta,sta+tmp.has[i]-,,i);
  127. sta+=tmp.has[i];
  128. }
  129. }else{
  130. int sta=l;
  131. for(int i=;i;i--)
  132. {
  133. if(!tmp.has[i])
  134. continue;
  135. update(,n,sta,sta+tmp.has[i]-,,i);
  136. sta+=tmp.has[i];
  137. }
  138. }
  139. }
  140. S_pushdown(,n,);
  141. for(int i=;i<=n;i++)
  142. printf("%c",ans[i]+'a'-);
  143. return ;
  144. }

代码(分块):

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. struct Area{
  6. int l,r;
  7. int lzt;//1 shenx -1 jiangx 0 wu
  8. int has[];
  9. }p[];
  10. int n,q;
  11. int a[];
  12. int blg[];
  13. int tmp[];
  14. char cmd[];
  15. bool cmp(int x,int y)
  16. {
  17. return x<y;
  18. }//shenx
  19. bool cmq(int x,int y)
  20. {
  21. return x>y;
  22. }//jiangx
  23. void P_sort(int x)
  24. {
  25. if(!p[x].lzt)
  26. return ;
  27. if(p[x].lzt==)
  28. {
  29. int t=;
  30. for(int i=p[x].l;i<=p[x].r;i++)
  31. {
  32. while(!p[x].has[t])
  33. t++;
  34. a[i]=t;
  35. p[x].has[t]--;
  36. }
  37. }
  38. if(p[x].lzt==-)
  39. {
  40. int t=;
  41. for(int i=p[x].l;i<=p[x].r;i++)
  42. {
  43. while(!p[x].has[t])
  44. t--;
  45. a[i]=t;
  46. p[x].has[t]--;
  47. }
  48. }
  49. p[x].lzt=;
  50. return ;
  51. }
  52. void build(int x)
  53. {
  54. for(int i=;i<=;i++)
  55. p[x].has[i]=;
  56. for(int i=p[x].l;i<=p[x].r;i++)
  57. p[x].has[a[i]]++;
  58. return ;
  59. }
  60. int main()
  61. {
  62. scanf("%d%d",&n,&q);
  63. if(n<=)
  64. {
  65. scanf("%s",cmd+);
  66. for(int i=;i<=n;i++)
  67. a[i]=cmd[i]-'a'+;
  68. for(int i=;i<=q;i++)
  69. {
  70. int l,r,op;
  71. scanf("%d%d%d",&l,&r,&op);
  72. if(l>r)
  73. std::swap(l,r);
  74. if(op==)
  75. std::sort(a+l,a+r+,cmq);
  76. else
  77. std::sort(a+l,a+r+,cmp);
  78. }
  79. for(int i=;i<=n;i++)
  80. printf("%c",a[i]+'a'-);
  81. puts("");
  82. return ;
  83. }
  84. scanf("%s",cmd+);
  85. int stan=(sqrt(n));
  86. for(int i=;i<=n;i++)
  87. {
  88. a[i]=cmd[i]-'a'+;
  89. blg[i]=i/stan+;
  90. p[blg[i]].has[a[i]]++;
  91. if(blg[i]!=blg[i-])
  92. {
  93. p[blg[i]].l=i;
  94. p[blg[i-]].r=i-;
  95. }
  96. }
  97. p[blg[n]].r=n;
  98. while(q--)
  99. {
  100. int l,r,op;
  101. scanf("%d%d%d",&l,&r,&op);
  102. if(l>r)
  103. std::swap(l,r);
  104. if(blg[l]==blg[r])
  105. {
  106. if(op==)
  107. std::sort(a+l,a+r+,cmq);
  108. else
  109. std::sort(a+l,a+r+,cmp);
  110. continue;
  111. }
  112. memset(tmp,,sizeof(tmp));
  113. P_sort(blg[l]);
  114. build(blg[l]);
  115. P_sort(blg[r]);
  116. build(blg[r]);
  117. for(int i=l;i<=p[blg[l]].r;i++)
  118. tmp[a[i]]++;
  119. for(int i=p[blg[r]].l;i<=r;i++)
  120. tmp[a[i]]++;
  121. for(int i=;i<=;i++)
  122. for(int j=blg[l]+;j<=blg[r]-;j++)
  123. tmp[i]+=p[j].has[i];
  124. if(op==)
  125. {
  126. int t=;
  127. for(int i=l;i<=p[blg[l]].r;i++)
  128. {
  129. while(!tmp[t])
  130. t--;
  131. tmp[t]--;
  132. a[i]=t;
  133. }
  134. build(blg[l]);
  135. for(int i=blg[l]+;i<=blg[r]-;i++)
  136. {
  137. int len=p[i].r-p[i].l+;
  138. for(int j=;j<=;j++)
  139. p[i].has[j]=;
  140. while(tmp[t]<len)
  141. {
  142. p[i].has[t]+=tmp[t];
  143. len-=tmp[t];
  144. tmp[t]=;
  145. t--;
  146. }
  147. if(len)
  148. {
  149. p[i].has[t]+=len;
  150. tmp[t]-=len;
  151. if(!tmp[t])
  152. t--;
  153. }
  154. p[i].lzt=-;
  155. }
  156. for(int i=p[blg[r]].l;i<=r;i++)
  157. {
  158. while(!tmp[t])
  159. t--;
  160. tmp[t]--;
  161. a[i]=t;
  162. }
  163. build(blg[r]);
  164. }else{
  165. int t=;
  166. for(int i=l;i<=p[blg[l]].r;i++)
  167. {
  168. while(!tmp[t])
  169. t++;
  170. tmp[t]--;
  171. a[i]=t;
  172. }
  173. build(blg[l]);
  174. for(int i=blg[l]+;i<=blg[r]-;i++)
  175. {
  176. int len=p[i].r-p[i].l+;
  177. for(int j=;j<=;j++)
  178. p[i].has[j]=;
  179. while(tmp[t]<len)
  180. {
  181. p[i].has[t]+=tmp[t];
  182. len-=tmp[t];
  183. tmp[t]=;
  184. t++;
  185. }
  186. if(len)
  187. {
  188. p[i].has[t]+=len;
  189. tmp[t]-=len;
  190. if(!tmp[t])
  191. t++;
  192. }
  193. p[i].lzt=;
  194. }
  195. for(int i=p[blg[r]].l;i<=r;i++)
  196. {
  197. while(!tmp[t])
  198. t++;
  199. tmp[t]--;
  200. a[i]=t;
  201. }
  202. build(blg[r]);
  203. }
  204. }
  205. for(int i=;i<=blg[n];i++)
  206. P_sort(i);
  207. for(int i=;i<=n;i++)
  208. printf("%c",a[i]+'a'-);
  209. puts("");
  210. return ;
  211. }

CF-558E (线段树/分块)的更多相关文章

  1. 洛谷 P5897 - [IOI2013]wombats(决策单调性优化 dp+线段树分块)

    题面传送门 首先注意到这次行数与列数不同阶,列数只有 \(200\),而行数高达 \(5000\),因此可以考虑以行为下标建线段树,线段树上每个区间 \([l,r]\) 开一个 \(200\times ...

  2. BZOJ 1798 (线段树||分块)的标记合并

    我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...

  3. [luogu1198][bzoj1012][JSOI2008]最大数【线段树+分块】

    题目描述 区间查询最大值,结尾插入,强制在线. 分析 线段树可以做,但是练了一下分块,发现自己打错了两个地方,一个是分块的地方把/打成了%,还有是分块的时候标号要-1. 其他也没什么要多讲的. 代码 ...

  4. L3-2 森森快递 (30 分)(贪心+线段树/分块)

    题目链接:https://pintia.cn/problem-sets/1108203702759940096/problems/1108204121661857798 题目大意: 森森开了一家快递公 ...

  5. 计蒜客16492 building(二分线段树/分块)

    题解: 考虑用线段树维护楼的最大值,然后这个问题就很简单了. 每次可以向左二分出比x高的第一个楼a,同理也可以向右二分出另一个楼b,如果a,b都存在,答案就是b-a-1. 注意到二分是可以直接在线段树 ...

  6. IOI 2013 袋熊(线段树+分块+决策单调性)

    题意 http://www.ioi2013.org/wp-content/uploads/tasks/day1/wombats/Wombats%20zh%20(CHN).pdf 思路 ​ 我们设矩形的 ...

  7. bzoj 3585 mex - 线段树 - 分块 - 莫队算法

    Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...

  8. 【模拟8.05】优美序列(线段树 分块 ST算法)

    如此显然的线段树,我又瞎了眼了 事实上跟以前的奇袭很像....... 只要满足公式maxn-minn(权值)==r-l即可 所以可以考虑建两颗树,一棵节点维护位置,一棵权值, 每次从一棵树树上查询信息 ...

  9. CF 19D 线段树+set压缩坐标轴+离散化map

    题意: n个操作,在200000*200000的平面上加删点 find 严格在坐标右上角,x最小,再y最小的点 线段树做,区间为离散化后的 X轴坐标 ,维护区间点数 和 最小的 y 值 ( 维护最小y ...

随机推荐

  1. atitit.js&#160;与c#&#160;java交互html5化的原理与总结.doc

    atitit.js 与c# java交互html5化的原理与总结.doc 1. 实现html5化界面的要解决的策略 1 1.1. Js交互 1 1.2. 动态參数个数 1 1.3. 事件监听 2 2. ...

  2. Magento--判断checkout中是否使用了coupon code

    在checkout页面中,如果想判断顾客是否有使用coupon code,可以通过checkout session来进行判断.以下代码会返回checkout中使用的coupon code或者返回空(当 ...

  3. Aizu - 2564 Tree Reconstruction 并查集

    Aizu - 2564 Tree Reconstruction 题意:一个有向图,要使得能确定每一条边的权值,要求是每个点的入权和出权相等,问你最少需要确定多少条边 思路:这题好像有一个定理之类的,对 ...

  4. tomcat安装部署

    1.tomcat6 下载地址 http://tomcat.apache.org/download-60.cgi 下载的话,下载那个.tar.gz后缀名的即可. 好像在 Linux.Unix上tomca ...

  5. Pycharm 的安装

    一. Windows 安装 汉化 破解补丁激活 下载 `https://pan.baidu.com/s/1qjI9uHaw0x374rwu6H8djA` 并将 JetbrainsCrack-2.8-r ...

  6. C# Cache的类方法

    public class DataCache    {        /// <summary>        /// 获取当前应用程序指定CacheKey的Cache值        / ...

  7. OPENCV(5) —— 图像直方图

    新版本对直方图不再使用之前的histogram的形式,而是用统一的Mat或者MatND的格式来存储直方图,可见新版本Mat数据结构的优势. C++: void calcHist(const Mat* ...

  8. SQL保存XML报错 “XML 分析: 行 1,字符 47,非法的 xml 字符”

    例如: <?xml version="1.0" encoding="utf-8" standalone="yes"?> < ...

  9. WPF通用框架ZFS《项目结构介绍01》_模块介绍

    首页介绍: 下图为项目运行首页图片, 大的结构分为三块: 1.Header首部模块(存放通知组件[全局通知.消息管理 ].扩展模块[皮肤.系统设置.关于作者.退出系统]) 2.Left左侧菜单模块(存 ...

  10. CodeForces 321 A - Ciel and Robot

    [题目链接]:click here~~ [题目大意]:一个robot 机器人 .能够依据给定的指令行动,给你四种指令,robot初始位置是(0,0).指令一出.robot会反复行动,推断是否能在无限行 ...