LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)
题目描述
给出一个长为 nn 的数列,以及 nn 个操作,操作涉及区间询问等于一个数 cc 的元素,并将这个区间的所有元素改为 cc。
输入格式
第一行输入一个数字 nn。
第二行输入 nn 个数字,第 i 个数字为 a_iai,以空格隔开。
接下来输入 nn 行询问,每行输入三个数字 ll、rr、cc,以空格隔开。
表示先查询位于 [l,r][l,r] 的数字有多少个是 cc,再把位于 [l,r][l,r] 的数字都改为 cc。
输出格式
对于每次询问,输出一行一个数字表示答案。
样例
样例输入
4
1 2 2 4
1 3 1
1 4 4
1 2 2
1 4 2
样例输出
1
1
0
2
数据范围与提示
对于 100\%100% 的数据,1 \leq n \leq 100000, -2^{31} \leq \mathrm{others}1≤n≤100000,−231≤others、\mathrm{ans} \leq 2^{31}-1ans≤231−1。
代码:
//#6284. 数列分块入门 8-区间查询等于一个数c的元素,并将这个区间的所有元素改为c
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+; int n,m;
int a[maxn],pos[maxn],tag[maxn]; int Find(int l,int r,int c)
{
int num=;
if(pos[l]==pos[r]){
if(tag[pos[l]]==c) num+=r-l+;
else{
if(tag[pos[l]]!=-){
for(int i=(pos[l]-)*m+;i<=pos[l]*m;i++)
a[i]=tag[pos[l]];
}
for(int i=l;i<=r;i++){
if(a[i]==c) num++;
else a[i]=c;
}
int flag=;
for(int i=(pos[l]-)*m+;i<=pos[l]*m;i++){
if(a[i]!=c){
flag=;break;
}
}
if(!flag) tag[pos[l]]=c;
else tag[pos[l]]=-;
}
}
else{
if(tag[pos[l]]==c){
num+=pos[l]*m-l+;
}
else{
if(tag[pos[l]]!=-){
for(int i=(pos[l]-)*m+;i<=pos[l]*m;i++)
a[i]=tag[pos[l]];
}
for(int i=l;i<=pos[l]*m;i++){
if(a[i]==c) num++;
else a[i]=c;
}
int flag=;
for(int i=(pos[l]-)*m+;i<=pos[l]*m;i++){
if(a[i]!=c){
flag=;break;
}
}
if(!flag) tag[pos[l]]=c;
else tag[pos[l]]=-;
}
for(int i=pos[l]+;i<pos[r];i++){
if(tag[i]==c) num+=m;
else{
if(tag[i]!=-) tag[i]=c;
else{
for(int j=(i-)*m+;j<=i*m;j++){
if(a[j]==c) num++;
else a[j]=c;
}
int flag=;
for(int j=(i-)*m+;j<=i*m;j++){
if(a[j]!=c){
flag=;break;
}
}
if(!flag) tag[i]=c;
else tag[i]=-;
}
}
}
if(tag[pos[r]]==c) num+=r-((pos[r]-)*m+)+;
else{
if(tag[pos[r]]!=-){
for(int i=(pos[r]-)*m+;i<=min(pos[r]*m,n);i++){
a[i]=tag[pos[r]];
}
}
for(int i=(pos[r]-)*m+;i<=r;i++){
if(a[i]==c) num++;
else a[i]=c;
}
int flag=;
for(int i=(pos[r]-)*m+;i<=min(pos[r]*m,n);i++){
if(a[i]!=c){
flag=;break;
}
}
if(!flag) tag[pos[r]]=c;
else tag[pos[r]]=-;
}
}
return num;
} int main()
{
scanf("%d",&n);
m=sqrt(n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
pos[i]=(i-)/m+;
}
memset(tag,-,sizeof(tag));
for(int i=;i<=n;i++){
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
printf("%d\n",Find(l,r,c));
}
} /*
10
1 3 4 2 5 7 11 3 5 1
1 2 1
2 4 2
3 5 3
4 6 4
5 9 4
3 5 1
7 9 4
5 9 4
3 7 2
5 6 2 1
1
0
0
2
0
3
4
0
2 */
LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)的更多相关文章
- LOJ.6284.数列分块入门8(分块)
题目链接 \(Description\) 给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c. \(Solution\) 模拟一些数据可以发现,询问后 ...
- [Libre 6281] 数列分块入门 5 (分块)
水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteu ...
- LOJ#6284. 数列分块入门 8
分块的时候开一个数组标记这个区间是不是都是一样颜色的部分,如果是的话,我后面的查询,更新部分就可以直接整块操作,对于不是不全部都一样颜色的块在具体进到快里面去暴力. 在更新的时候对边上的两个不完整的块 ...
- LOJ.6281.数列分块入门5(分块 区间开方)
题目链接 int内的数(也不非得是int)最多开方4.5次就变成1了,所以还不是1就暴力,是1就直接跳过. #include <cmath> #include <cstdio> ...
- LibreOJ 6277 数列分块入门 1(分块)
题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...
- LibreOJ 6280 数列分块入门 4(分块区间加区间求和)
题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个su ...
- LibreOJ 6278 数列分块入门 2(分块)
题解:非常高妙的分块,每个块对应一个桶,桶内元素全部sort过,加值时,对于零散块O(sqrt(n))暴力修改,然后暴力重构桶.对于大块直接整块加.查询时对于非完整块O(sqrt(n))暴力遍历.对 ...
- LibreOJ 6281 数列分块入门 5(分块区间开方区间求和)
题解:区间开方emmm,这马上让我想起了当时写线段树的时候,很显然,对于一个在2^31次方以内的数,开方7-8次就差不多变成一了,所以我们对于每次开方,如果块中的所有数都为一了,那么开方也没有必要了. ...
- LibreOJ 6279 数列分块入门 3(分块+排序)
题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x ...
随机推荐
- 解决华为手机用rem单位,内容超出屏幕宽度问题
在H5手机页面上,用rem单位布局,配合js计算出一个根节点的font-size(原理是屏幕宽度乘以一个固定比例,如1/100),之后页面中所有的px全都换算成了rem单位来写,优点是能适配各种不同屏 ...
- HDU 5533Dancing Stars on Me 基础几何
Problem Description The sky was brushed clean by the wind and the stars were cold in a black sky. Wh ...
- Linux修改服务器ip
Linux基础二(修改ip地址.修改网关.修改DNS服务器.重新启动网络配置) 网络的初始化 .ip地址的修改(临时生效) 使用ifconfig命令 ifconfig 网卡名 ip地址 netma ...
- Linux之防火墙与端口
1.关闭所有的 INPUT FORWARD OUTPUT 只对某些端口开放.下面是命令实现: iptables -P INPUT DROPiptables -P FORWARD DROPiptable ...
- 【spoj1182/usaco-Cow Queueing, 2003 Dec-二进制编号】数位dp
题意:定义新的排序:先按一个数中二进制中1的个数从小到大排序,如果1的个数相同则按数的大小从小到大排序.问[A,B]之间有第K大的数是哪个.-2^31<=A,B<=2^31(A,B必定同正 ...
- centos6.5下安装svn并且实现多项目管理配置方案
#安装SVN服务器 yum install subversion #在home下创建svn根目录 mkdir /home/svn #在 /home/svn下创建pro1 , pro2, pro3 三个 ...
- React的单向数据流与组件间的沟通
今天来给大家总结下React的单向数据流与组件间的沟通. 首先,我认为使用React的最大好处在于:功能组件化,遵守前端可维护的原则. 先介绍单向数据流吧. React单向数据流: React是单向数 ...
- Perl6 Bailador框架(8):自定义400/500
第一种方法, 直接写在源码中: use Bailador; get '/' => sub { '<h1>hello, Bailador</h1>'; } get '/te ...
- python基础===两个list之间移动元素
首先我们先了解一下list的几个常用函数: a = [123,456,"tony","jack"] #list中增加元素a.append("www&q ...
- python基础===解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX(转载)
本文转自:解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX 从网上抓了一些字 ...