前几天写莫队有点上瘾,想起好久没有写过分块了,就来写一道分块题

题意很简单

给定一个序列,要求维护以下操作
把区间\([l,r]\)中所有大于\(x\)的数减去\(x\)
查询区间\([l,r]\)中等于\(x\)的数的个数

很显然的,这些操作都主要与权值有关
所以按权值维护
但是任意区间不方便维护,考虑分块

同一个块中如果只有整块的修改
显然如果两个位置权值一样
不管怎么改还是一样的
所以可以用并查集
只修改一个点,合并也是\(O(1)\)的

但是如果直接修改所有大于\(x\)的显然会超时
所以如果大于\(x\)的比较少就直接修改大于\(x\)的(复杂度\(O(max-x)\),\(max\)是块内最大值)
否则修改小于等于\(x\)的部分(加上\(x\)),然后打一个整块减的标记(复杂度\(O(x)\))
具体来说如果\(x*2>max\)就改大的部分否则改小的部分
因为每次修改都会使\(max\)减小\(x\)且每次复杂度都是\(O(x)\)
所以均摊复杂度\(O(n*\sqrt n)\)

然后写出来,调试了半天,终于过了

然后打开五彩斑斓的世界直接把Welcome home, Chtholly的代码交上去

MLE,\(30pts\)
发现空间限制变成了原来的\(\frac{1}{4}\)
卡空间后在BZOJ交了一发,过了
兴高采烈地又去洛谷交了一发,TLE\(90pts\)
发现时间限制变成了原来的\(\frac{1}{3}\)

于是又卡了半个小时的常
最后改得无比丑陋终于卡过了

\(100pts\)代码惨不忍睹
还是贴\(90pts\)的吧

#include<bits/stdc++.h>using namespace std;#define gc c=getchar()
#define r(x) read(x)template<typename T>
inline void read(T&x){x=0;T k=1;char gc;while(!isdigit(c)){if(c=='-')k=-1;gc;}while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
}const int N=1e5+7;
const int len=320;int fa[N];
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);
}int mx[len],L[len],R[len];
int rt[len][N];
unsigned short cnt[N];
int a[N];
inline void build(int x){mx[x]=0;for(int i=L[x];i<=R[x];++i){if(!rt[x][a[i]]){rt[x][a[i]]=i;fa[i]=i;cnt[rt[x][a[i]]]=1;mx[x]=max(mx[x],a[i]);}else {fa[i]=rt[x][a[i]];cnt[rt[x][a[i]]]++;}}
}int tag[len];
inline void pushdown(int x){for(int i=L[x];i<=R[x];++i){a[i]=a[find(i)];cnt[rt[x][a[i]]]=0;rt[x][a[i]]=0;}for(int i=L[x];i<=R[x];++i)a[i]-=tag[x];for(int i=L[x];i<=R[x];++i)fa[i]=0;tag[x]=0;
}unsigned short be[N];
inline void modify1(int l,int r,int v){for(int i=be[l];i<=be[r];++i)pushdown(i);for(int i=l;i<=r;++i)if(a[i]>v)a[i]-=v;for(int i=be[l];i<=be[r];++i)build(i);
}inline void insert(int x,int p,int q){if(!rt[x][p])return;if(!rt[x][q]){rt[x][q]=rt[x][p];cnt[rt[x][q]]=cnt[rt[x][p]];a[rt[x][p]]=q;}else {fa[rt[x][p]]=rt[x][q];cnt[rt[x][q]]+=cnt[rt[x][p]];}rt[x][p]=0;cnt[rt[x][p]]=0;
}inline void modify2(int x,int v){if(v>=mx[x]-tag[x])return;if(v*2>mx[x]-tag[x]){for(int i=v+tag[x]+1;i<=mx[x];++i)insert(x,i,i-v);mx[x]=max(mx[x]-v,v+tag[x]);}else {for(int i=tag[x]+1;i<=tag[x]+v;++i)insert(x,i,i+v);tag[x]+=v;}
}inline void modify(int l,int r,int v){if(be[l]+1>=be[r])modify1(l,r,v);else {modify1(l,R[be[l]],v);modify1(L[be[r]],r,v);for(int i=be[l]+1;i<be[r];++i)modify2(i,v);}
}inline int query1(int l,int r,int v){int ret=0;for(int i=l;i<=r;++i)if(a[find(i)]-tag[be[i]]==v)ret++;return ret;
}inline int query2(int x,int v){if(v+tag[x]>1e5)return 0;return cnt[rt[x][v+tag[x]]];
}inline int query(int l,int r,int v){if(be[l]+1>=be[r])return query1(l,r,v);else {int ret=query1(l,R[be[l]],v)+query1(L[be[r]],r,v);for(int i=be[l]+1;i<be[r];++i)ret+=query2(i,v);return ret;}
}int main(){int n,m;r(n),r(m);int block_size=sqrt(n);for(int i=1;i<=n;++i){r(a[i]);be[i]=(i-1)/block_size+1;if(!L[be[i]])L[be[i]]=i;R[be[i]]=i;}for(int i=1;i<=be[n];++i)build(i);for(int opt,l,r,x;m;--m){r(opt),r(l),r(r),r(x);if(opt==1)modify(l,r,x);else printf("%d\n",query(l,r,x));}
}

转载于:https://www.cnblogs.com/yicongli/p/9831742.html

Welcome home, Chtholly [Ynoi2018]五彩斑斓的世界相关推荐

  1. CF896E Welcome home,Chtholly/[Ynoi2018]五彩斑斓的世界(并查集+第二分块)

    CF896E Welcome home,Chtholly/[Ynoi2018]五彩斑斓的世界 description solution code description 五彩斑斓的世界 CF896E ...

  2. P4117 [Ynoi2018] 五彩斑斓的世界

    P4117 [Ynoi2018] 五彩斑斓的世界 给你一个长为 nnn 的序列 aaa,有 mmm 次操作: 把区间 [l,r][l,r][l,r] 中大于 xxx 的数减去 xxx. 查询区间 [l ...

  3. 题解 P4117 【[Ynoi2018]五彩斑斓的世界】

    题目链接 我觉得AVX2指令集不够爽,于是写了AVX512.到官网查了一天手册,直接拿下最优解 Solution [Ynoi2018]五彩斑斓的世界 题目大意:给定一个长度为\(n\)的序列.每次将\ ...

  4. P4117 [Ynoi2018] 五彩斑斓的世界 题解

    这题目很难,我花了三周,但题目中的图片是真的那个什么的:[Ynoi2018] 五彩斑斓的世界 - 洛谷 结尾有题目中的图片 我们先搞清楚一个前置问题:把区间 [l,r][l,r] 中所有的 xx 变成 ...

  5. [Ynoi2018]五彩斑斓的世界

    五彩斑斓的世界 题解 这道题相当于是Welcome home, Chtholly的数据加强版 ,对,就是那个臭名昭著的瑟尼欧里斯树的那场比赛的最后一道题. 于是lxllxllxl亲切地将这道题命名为第 ...

  6. bzoj 5143 [Ynoi2018]五彩斑斓的世界

           二阶堂真红给了你一个长为n的序列a,有m次操作        1.把区间[l,r]中大于x的数减去x        2.查询区间[l,r]中x的出现次数        题解:       ...

  7. luogu P4117 [Ynoi2018] 五彩斑斓的世界

    https://www.luogu.com.cn/problem/P4117 因为题目的值域只有10510^5105,并且只有减法一种操作,所以我们可以考虑均摊 把所有的减法改成加法 首先还是要分块, ...

  8. 2018十二月刷题列表

    Preface \(2018\)年的尾巴,不禁感慨自己这一年的蜕变只能用蜕变来形容了. 而且老叶说我们今年没的参加清北冬令营可以参加CCF在广州二中举办的冬令营,只要联赛\(390+\)就应该可以报. ...

  9. NOIP前的刷题记录

    因为这几天要加油,懒得每篇都来写题解了,就这里记录一下加上一句话题解好了 P4071 [SDOI2016]排列计数   组合数+错排 loj 6217 扑克牌 暴力背包 P2511 [HAOI2008 ...

  10. 上次吹的牛实现后,李彦宏又在百度世界大会立了三个flag!

    7月4日百度 AI 开发者大会上,李彦宏说:"曾经吹过的牛实现了,全球首款 L4 级量产自动驾驶巴士'阿波龙'量产下线!" 如今,阿波龙已经安全运营了整整120天. 4个月后的今天 ...

最新文章

  1. java强制转换_java强制类型转换
  2. 【完整代码】Scala akka入门示例
  3. 怎么获取codeforces的数据_手把手教你学会新媒体运营——如何通过数据分析来优化新媒体运营...
  4. web input光标的颜色
  5. 最简单的 post 请求发起方式、调用其它系统接口
  6. 计算机应用基础文字处理软件应用职高PPT,《计算机应用基础》职高2010修订版_教(学)案...
  7. Pytest之参数化
  8. Spark数据分析技术学习笔记(三)——Spark累加器
  9. Volley(六 )—— 从源码带看Volley的缓存机制
  10. 关于try...catch...finally中return的疑惑
  11. c#使用类库nthereum在.net上开发以太坊的实战示例
  12. 分享4个不错的软件资源下载网站(值得珍藏)
  13. Kaggle TMDB电影数据分析项目实战
  14. 图片放大以后不清晰怎么办?
  15. 大数据云计算实习报告
  16. warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  17. android 打开pdf文件
  18. 论文阅读一《Region Proposal by Guided Anchoring》
  19. 雷声大雨点小:Bakkt「见光死」了吗?
  20. C# 利用正则表达式获取文本中的https网址并替换新的对应的值,微信小程序播放腾讯视频

热门文章

  1. Ant Design vue v-decorate 进行数据绑定
  2. c++initgraph函数_二次函数图像绕其顶点旋转180°后所得图像的解析式
  3. mysql 执行delete引发死锁问题
  4. NPM install报错certificate has expired
  5. Python/Basemap绘制美国人口分布示意图
  6. 调出软键盘 挤掉标题栏咋办
  7. ubuntu18.04+opencv3.4.10+opencv3.4.10contrib+LSD使用
  8. VS2019 添加一组控件到工具箱
  9. 自动驾驶芯片之——FPGA和ASIC介绍
  10. php如何调用protected,PHP中类作用域protected实例详解