数列分块是莫队分块的前置技能,练习一下

1.loj6277

给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值。

直接分块+tag即可

#include <bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define per(ii,a,b) for(int ii=a;ii>=b;ii--)
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
int size;
ll num[maxn],tag[maxn];
int id[maxn];
void update(int s,int t,ll x){
for(int i=s;i<=min(id[s]*size,t);i++)
num[i]+=x;
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++)
num[i]+=x;
}
for(int i=id[s]+1;i<=id[t]-1;i++){
tag[i]+=x;
}
} int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
scanf("%d",&n);
size=sqrt(n);
for(int i=1;i<=n;i++) scanf("%lld",num+i);
for(int i=1;i<=n;i++) id[i]=(i-1)/size+1;
for(int i=1;i<=n;i++){
int flag,a,b;
ll c;
scanf("%d%d%d%lld",&flag,&a,&b,&c);
if(flag==0) update(a,b,c);
else printf("%lld\n",num[b]+tag[id[b]]);
}
#ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

  

2.loj6278

给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的元素个数。

分块,,用vector可以很方便得保存排序结果,每次修改两端应该重新排序

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
int size;
ll num[maxn],tag[maxn];
vector<ll>rk[maxn/100];
int id[maxn];
void reset(int pos){
rk[pos].clear();
for(int i=(pos-1)*size+1;i<=min(pos*size,n);i++)
rk[pos].push_back(num[i]);
sort(rk[pos].begin(),rk[pos].end());
}
void update(int s,int t,ll x){
for(int i=s;i<=min(id[s]*size,t);i++)
num[i]+=x;
reset(id[s]);
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++)
num[i]+=x;
reset(id[t]);
}
for(int i=id[s]+1;i<=id[t]-1;i++){
tag[i]+=x;
}
}
int query(int s,int t,ll k){
int ans=0;
for(int i=s;i<=min(id[s]*size,t);i++){
if(num[i]+tag[id[s]]<k)ans++;
}
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++){
if(num[i]+tag[id[t]]<k)ans++;
}
}
for(int i=id[s]+1;i<=id[t]-1;i++){
ans+=lower_bound(rk[i].begin(),rk[i].end(),(ll)k-tag[i])-rk[i].begin();
}
return ans;
}
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
scanf("%d",&n);
size=sqrt(n);
for(int i=1;i<=n;i++) scanf("%lld",num+i);
for(int i=1;i<=n;i++) {
id[i]=(i-1)/size+1;
rk[id[i]].push_back(num[i]);
}
for(int i=1;i<=n;i++)
sort(rk[i].begin(),rk[i].end());
for(int i=1;i<=n;i++){
int flag,a,b;
ll c;
scanf("%d%d%d%lld",&flag,&a,&b,&c);
if(flag==0) update(a,b,c);
else printf("%d\n",query(a,b,c*c));
}
#ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

3.loj6279

给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的前驱(比其小的最大元素)

用多重集合维护块内元素,注意两端的部分需要重建

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
int size;
ll num[maxn],tag[maxn];
multiset<ll>vis[maxn/100];
int id[maxn];
void update(int s,int t,ll x){
for(int i=s;i<=min(id[s]*size,t);i++){
vis[id[s]].erase(num[i]);
num[i]+=x;
vis[id[s]].insert(num[i]);
}
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++){
vis[id[t]].erase(num[i]);
num[i]+=x;
vis[id[t]].insert(num[i]);
}
}
for(int i=id[s]+1;i<=id[t]-1;i++){
tag[i]+=x;
}
}
ll query(int s,int t,ll k){
ll ans=-1;
for(int i=s;i<=min(id[s]*size,t);i++){
ll tmp=num[i]+tag[id[s]];
if(tmp<k) ans=max(ans,tmp);
}
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++){
ll tmp=num[i]+tag[id[t]];
if(tmp<k) ans=max(ans,tmp);
}
}
for(int i=id[s]+1;i<=id[t]-1;i++){
int tmp=k-tag[i];
multiset<ll>::iterator it=vis[i].lower_bound(tmp);
if(it==vis[i].begin()) continue;
--it;
ans=max(ans,*it+tag[i]);
}
return ans;
}
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
scanf("%d",&n);
size=sqrt(n);
for(int i=1;i<=n;i++) scanf("%lld",num+i);
for(int i=1;i<=n;i++) {
id[i]=(i-1)/size+1;
vis[id[i]].insert(num[i]);
}
for(int i=1;i<=n;i++){
int flag,a,b;
ll c;
scanf("%d%d%d%lld",&flag,&a,&b,&c);
if(flag==0) update(a,b,c);
else printf("%d\n",query(a,b,c));
}
#ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

4.loj6280

给出一个长为n的数列,以及n个操作,操作涉及区间加法,区间求和。

直接分块,同时需要维护一个块元素和

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
int size;
ll num[maxn],tag[maxn],sum[maxn];
int id[maxn];
void update(int s,int t,ll x){
for(int i=s;i<=min(id[s]*size,t);i++){
num[i]+=x;
}
sum[id[s]]+=x*(min(id[s]*size,t)-s+1);
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++){
num[i]+=x;
}
sum[id[t]]+=(t-(id[t]-1)*size)*x;
}
for(int i=id[s]+1;i<=id[t]-1;i++){
tag[i]+=x;
}
}
ll query(int s,int t){
ll ans=0;
for(int i=s;i<=min(id[s]*size,t);i++){
ans+=num[i]+tag[id[s]];
}
if(id[s]!=id[t]){
for(int i=(id[t]-1)*size+1;i<=t;i++){
ans+=num[i]+tag[id[t]];
}
}
for(int i=id[s]+1;i<=id[t]-1;i++){
ans+=sum[i]+tag[i]*size;
}
return ans;
}
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
scanf("%d",&n);
size=sqrt(n);
for(int i=1;i<=n;i++) scanf("%lld",num+i);
for(int i=1;i<=n;i++) {
id[i]=(i-1)/size+1;
sum[id[i]]+=num[i];
}
for(int i=1;i<=n;i++){
int flag,a,b;
ll c;
scanf("%d%d%d%lld",&flag,&a,&b,&c);
if(flag==0) update(a,b,c);
else printf("%lld\n",query(a,b)%(c+1));
}
#ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

(其实LOJ的题目数据比较水,欢迎hack我)

LOJ 6277-6280 数列分块入门 1-4的更多相关文章

  1. LOJ 6277:数列分块入门 1(分块入门)

    #6277. 数列分块入门 1 内存限制:256 MiB时间限制:100 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论 3 测试数据 题目描述 给出一 ...

  2. LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)

    #6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论   题目描述 给出一个 ...

  3. loj 6278 6279 数列分块入门 2 3

    参考:「分块」数列分块入门1 – 9 by hzwer 2 Description 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,询问区间内小于某个值\(x\)的元素个数. 思 ...

  4. LOJ#6280. 数列分块入门 4

    另外开一个数组维护每一个块内的总和. 给区间加值是,残余的块一个一个点更新,整个的块一次性更新 查询的时候也是,残余的块一个一个点加,整个的块一次性加 #include<map> #inc ...

  5. LibreOJ 6280 . 数列分块入门 4

    题目链接:https://loj.ac/problem/6280 加一个数组保存块的和. 代码: #include<iostream> #include<cstring> #i ...

  6. 【LibreOJ 6277】数列分块入门 1 (分块)

    emmm-学下分块~ 区间:数列中连续一段的元素 区间操作:将某个区间[a,b]的所有元素进行某种改动的操作 块:我们将数列划分成若干个不相交的区间,每个区间称为一个块 整块:在一个区间操作时,完整包 ...

  7. LibreOJ 6280 数列分块入门 4(分块区间加区间求和)

    题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个su ...

  8. 【LOJ#6277】数列分块1

    题目大意:维护一个长度为 N 的序列,支持区间修改.单点查询. 代码如下 #include <bits/stdc++.h> using namespace std; const int m ...

  9. LOJ——#6277. 数列分块入门 1

    ~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法——分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...

  10. 数列分块入门1-9 By hzwer

    声明 持续更新,因为博主也是正在学习分块的知识,我很菜的,菜的抠$jio$ 写在前面 分块是个很暴力的算法,但却比暴力优秀的多,分块算法的时间复杂度一般是根号的,他的主要思想是将一个长度是$n$的数列 ...

随机推荐

  1. Hadoop记录-hadoop2.x常用端口及定义方法

    Hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以及HTTP访问.而随着Hadoop周边组件的增多,完全记不住哪个端口对应哪个应用,特收集记录如 ...

  2. MDB数据类型注意事项

    在ArcGIS中,对MDB数据类型的支持较少,如下图: 当时当你打开Access软件的时候,你会发现文本类型,其实有很多种: 假如涉及到的字段类型是文本,而且又比较长,最好设置为“备注”

  3. jsp过滤器

    1.ip过滤 IpFilter: package com.cn.filter; import java.io.IOException; import javax.servlet.Filter; imp ...

  4. Java8新特性 并行流与串行流 Fork Join

    并行流就是把一个内容分成多个数据块,并用不同的线程分 别处理每个数据块的流. Java 8 中将并行进行了优化,我们可以很容易的对数据进行并 行操作. Stream API 可以声明性地通过 para ...

  5. 【小玩意】time-passing-by clock

    就着youtube上的教程用html和js做了个小时钟. Code: clock.html //clock.html <!DOCTYPE html> <html> <he ...

  6. javascript给定了日期如何获得星期几

    1.这可以用JavaScript的Date对象的getDay方法.如:获取当天是星期几,则为:new Date().getDay();//返回0-6,0对应星期天,1-6对应星期一到星期六2.如果想给 ...

  7. vue找错

    第一,vue报错直接用浏览器的console查看,不用代码寻找: 第二,props继承父类之后,然后作用到注册组件,同一个时间不可以取值,因为props模板还没有值

  8. Coursera, Machine Learning, SVM

    Support Vector Machine (large margin classifiers ) 1. cost function and hypothesis 下面那个紫色线就是SVM 的cos ...

  9. loj 6436 PKUSC2018 神仙的游戏

    传送门 好妙蛙 即串\(s\)长度为\(n\)首先考虑如果一个长度为\(len\)的\(border\)存在,当且仅当对所有\(i\in[1,len],s[i]=s[n-len+i]\),也就是所有模 ...

  10. JavaScript面试技巧(一):基础知识

    1.变量类型和计算 变量类型:值类型.引用类型.typeof运算符. 变量计算:字符串拼接.==运算符.if语句.逻辑运算符 2.原型和原型链 构造函数 5个原型规则 3.作用域和闭包-执行上下文 4 ...