数列分块入门1~9 loj6277~6285
一
给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,单点查值。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, a[50005], opt, uu, vv, ww, tag[305], blc, bel[50005];
void add(int uu, int vv, int ww){
int p=bel[uu], q=bel[vv];
if(p==q)
for(int i=uu; i<=vv; i++)
a[i] += ww;
else{
for(int i=p+1; i<=q-1; i++) tag[i] += ww;
for(int i=uu; i<=bel[uu]*blc; i++) a[i] += ww;
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++) a[i] += ww;
}
}
int main(){
cin>>n;
blc = sqrt(n);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
for(int i=1; i<=n; i++) bel[i] = (i - 1) / blc + 1;
for(int i=1; i<=n; i++){
scanf("%d %d %d %d", &opt, &uu, &vv, &ww);
if(!opt) add(uu, vv, ww);
else printf("%d\n", a[vv]+tag[bel[vv]]);
}
return 0;
}
二
给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的元素个数。
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
int n, blc, a[50005], tag[50005], bel[50005], opt, uu, vv, ww;
vector<int> vec[50005];
void qwq(int tat){
vec[tat].clear();
for(int i=(tat-1)*blc+1; i<=min(tat*blc, n); i++) vec[tat].push_back(a[i]);
sort(vec[tat].begin(), vec[tat].end());
}
void update(int uu, int vv, int ww){
if(bel[uu]==bel[vv]){
for(int i=uu; i<=vv; i++) a[i] += ww;
qwq(bel[uu]);
}
else{
for(int i=bel[uu]+1; i<=bel[vv]-1; i++) tag[i] += ww;
for(int i=uu; i<=bel[uu]*blc; i++) a[i] += ww;
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++) a[i] += ww;
qwq(bel[uu]); qwq(bel[vv]);
}
}
int query(int uu, int vv, int ww){
int re=0;
if(bel[uu]==bel[vv]){
for(int i=uu; i<=vv; i++)
if(a[i]+tag[bel[i]]<ww)
re++;
}
else{
for(int i=bel[uu]+1; i<=bel[vv]-1; i++)
re += lower_bound(vec[i].begin(), vec[i].end(), ww-tag[i]) - vec[i].begin();
for(int i=uu; i<=bel[uu]*blc; i++)
if(a[i]+tag[bel[i]]<ww)
re++;
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++)
if(a[i]+tag[bel[i]]<ww)
re++;
}
return re;
}
int main(){
cin>>n;
blc = sqrt(n/200);
for(int i=1; i<=n; i++){
bel[i] = (i - 1) / blc + 1;
scanf("%d", &a[i]);
vec[bel[i]].push_back(a[i]);
}
for(int i=1; i<=n; i=bel[i]*blc+1)
sort(vec[bel[i]].begin(), vec[bel[i]].end());
for(int i=1; i<=n; i++){
scanf("%d %d %d %d", &opt, &uu, &vv, &ww);
if(!opt) update(uu, vv, ww);
else printf("%d\n", query(uu, vv, ww*ww));
}
return 0;
}
三
给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的前驱(比其小的最大元素)。
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
int n, blc, a[100005], bel[100005], tag[100005], opt, uu, vv, ww;
vector<int> vec[100005];
void qwq(int u){
vec[u].clear();
for(int i=(u-1)*blc+1; i<=min(n, blc*u); i++)
vec[u].push_back(a[i]);
sort(vec[u].begin(), vec[u].end());
}
void update(int uu, int vv, int ww){
if(bel[uu]==bel[vv]){
for(int i=uu; i<=vv; i++)
a[i] += ww;
qwq(bel[uu]);
}
else{
for(int i=bel[uu]+1; i<=bel[vv]-1; i++) tag[i] += ww;
for(int i=uu; i<=bel[uu]*blc; i++) a[i] += ww;
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++) a[i] += ww;
qwq(bel[uu]); qwq(bel[vv]);
}
}
int query(int uu, int vv, int ww){
int re=0xffffffff;
if(bel[uu]==bel[vv]){
for(int i=uu; i<=vv; i++)
if(a[i]+tag[bel[i]]<ww)
re = max(re, a[i]+tag[bel[i]]);
}
else{
for(int i=bel[uu]+1; i<=bel[vv]-1; i++){
int pos=lower_bound(vec[i].begin(), vec[i].end(), ww-tag[i])-vec[i].begin();
if(pos) re = max(re, vec[i][pos-1]+tag[i]);
}
for(int i=uu; i<=bel[uu]*blc; i++)
if(a[i]+tag[bel[i]]<ww)
re = max(re, a[i]+tag[bel[i]]);
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++)
if(a[i]+tag[bel[i]]<ww)
re = max(re, a[i]+tag[bel[i]]);
}
if(re==0xffffffff) return -1;
else return re;
}
int main(){
cin>>n;
blc = sqrt(n*log(n)/log(2));
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
bel[i] = (i - 1) / blc + 1;
vec[bel[i]].push_back(a[i]);
}
for(int i=1; i<=n; i=bel[i]*blc+1)
sort(vec[bel[i]].begin(), vec[bel[i]].end());
for(int i=1; i<=n; i++){
scanf("%d %d %d %d", &opt, &uu, &vv, &ww);
if(!opt) update(uu, vv, ww);
else printf("%d\n", query(uu, vv, ww));
}
return 0;
}
四
给出一个长为n的数列,以及n个操作,操作涉及区间加法,区间求和。
五
给出一个长为n的数列,以及n个操作,操作涉及区间开方,区间求和。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, blc, bel[50005], opt, uu, vv, ww, tag[50005], sum[50005], a[50005];
int qwq(int uu, int vv){
for(int i=uu; i<=vv; i++){
sum[bel[i]] -= a[i];
a[i] = sqrt(a[i]);
sum[bel[i]] += a[i];
}
return sum[bel[uu]];
}
void qaq(int u){
if(tag[u]) return ;
int re=qwq((u-1)*blc+1, u*blc);
if(re>blc) tag[u] = false;
else tag[u] = true;
}
void update(int uu, int vv){
if(bel[uu]==bel[vv])
qwq(uu, vv);
else{
for(int i=bel[uu]+1; i<=bel[vv]-1; i++) qaq(i);
qwq(uu, bel[uu]*blc);
qwq((bel[vv]-1)*blc+1, vv);
}
}
int query(int uu, int vv){
int re=0;
if(bel[uu]==bel[vv])
for(int i=uu; i<=vv; i++)
re += a[i];
else{
for(int i=bel[uu]+1; i<=bel[vv]-1; i++) re += sum[i];
for(int i=uu; i<=bel[uu]*blc; i++) re += a[i];
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++) re += a[i];
}
return re;
}
int main(){
cin>>n;
blc = sqrt(n);
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
bel[i] = (i - 1) / blc + 1;
sum[bel[i]] += a[i];
}
for(int i=1; i<=n; i++){
scanf("%d %d %d %d", &opt, &uu, &vv, &ww);
if(!opt) update(uu, vv);
else printf("%d\n", query(uu, vv));
}
return 0;
}
六
给出一个长为n的数列,以及n个操作,操作涉及单点插入,单点询问,数据随机生成。
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
typedef pair<int,int> par;
int n, blc, opt, uu, vv, ww, sta[200005], din, m;
vector<int> vec[200005];
par query(int uu){
int x=1;
while(uu>vec[x].size()){
uu -= vec[x].size();
x++;
}
return make_pair(x, uu-1);
}
void rebuild(){
din = 0;
for(int i=1; i<=m; i++){
for(int j=0; j<vec[i].size(); j++)
sta[++din] = vec[i][j];
vec[i].clear();
}
blc = sqrt(din);
for(int i=1; i<=din; i++)
vec[(i-1)/blc+1].push_back(sta[i]);
}
void update(int uu, int vv){
par re=query(uu);
vec[re.first].insert(vec[re.first].begin()+re.second, vv);
if(vec[re.first].size()>blc+blc) rebuild();
}
int main(){
cin>>n;
blc = sqrt(n);
m = (n - 1) / blc + 1;
for(int i=1; i<=n; i++){
scanf("%d", &uu);
vec[(i-1)/blc+1].push_back(uu);
}
for(int i=1; i<=n; i++){
scanf("%d %d %d %d", &opt, &uu, &vv, &ww);
if(!opt) update(uu, vv);
else{
par re=query(vv);
printf("%d\n", vec[re.first][re.second]);
}
}
return 0;
}
七
给出一个长为n的数列,以及n个操作,操作涉及区间乘法,区间加法,单点询问。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, a[100005], bel[100005], add[100005], mul[100005], blc;
int opt, uu, vv, ww;
const int mod=10007;
void pushDown(int x){
for(int i=(x-1)*blc+1; i<=min(n, x*blc); i++)
a[i] = (a[i] * mul[x] + add[x]) % mod;
mul[x] = 1; add[x] = 0;
}
void updAdd(int uu, int vv, int ww){
pushDown(bel[uu]);
if(bel[uu]==bel[vv])
for(int i=uu; i<=vv; i++)
a[i] = (a[i] + ww) % mod;
else{
pushDown(bel[vv]);
for(int i=bel[uu]+1; i<=bel[vv]-1; i++) add[i] = (add[i] + ww) % mod;
for(int i=uu; i<=bel[uu]*blc; i++) a[i] = (a[i] + ww) % mod;
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++) a[i] = (a[i] + ww) % mod;
}
}
void updMul(int uu, int vv, int ww){
pushDown(bel[uu]);
if(bel[uu]==bel[vv])
for(int i=uu; i<=vv; i++)
a[i] = (a[i] * ww) % mod;
else{
pushDown(bel[vv]);
for(int i=bel[uu]+1; i<=bel[vv]-1; i++){
mul[i] = (mul[i] * ww) % mod;
add[i] = (add[i] * ww) % mod;
}
for(int i=uu; i<=bel[uu]*blc; i++) a[i] = (a[i] * ww) % mod;
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++) a[i] = (a[i] * ww) % mod;
}
}
int main(){
cin>>n;
blc = sqrt(n);
for(int i=1; i<=n; i++){
mul[i] = 1;
scanf("%d", &a[i]);
bel[i] = (i - 1) / blc + 1;
}
for(int i=1; i<=n; i++){
scanf("%d %d %d %d", &opt, &uu, &vv, &ww);
if(!opt) updAdd(uu, vv, ww);
else if(opt==1) updMul(uu, vv, ww);
else printf("%d\n", (a[vv]*mul[bel[vv]]+add[bel[vv]])%mod);
}
return 0;
}
八
给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, a[100005], tag[100005], bel[100005], blc, uu, vv, ww;
void pushDown(int x){
if(tag[x]==-1) return ;
for(int i=(x-1)*blc+1; i<=min(n, x*blc); i++)
a[i] = tag[x];
tag[x] = -1;
}
int update(int uu, int vv, int ww){
int re=0;
if(tag[uu]) pushDown(bel[uu]);
if(bel[uu]==bel[vv])
for(int i=uu; i<=vv; i++){
if(a[i]==ww)
re++;
a[i] = ww;
}
else{
if(tag[vv]) pushDown(bel[vv]);
for(int i=bel[uu]+1; i<=bel[vv]-1; i++){
if(tag[i]!=-1)
re += tag[i]==ww?blc:0;
else
for(int j=(i-1)*blc+1; j<=i*blc; j++)
re += a[j]==ww;
tag[i] = ww;
}
for(int i=uu; i<=bel[uu]*blc; i++){
re += a[i]==ww;
a[i] = ww;
}
for(int i=(bel[vv]-1)*blc+1; i<=vv; i++){
re += a[i]==ww;
a[i] = ww;
}
}
return re;
}
int main(){
cin>>n;
blc = sqrt(n);
for(int i=1; i<=n; i++){
tag[i] = -1;
scanf("%d", &a[i]);
bel[i] = (i - 1) / blc + 1;
}
for(int i=1; i<=n; i++){
scanf("%d %d %d", &uu, &vv, &ww);
printf("%d\n", update(uu, vv, ww));
}
return 0;
}
九
区间众数
参考luogu4168 蒲公英
数列分块入门1~9 loj6277~6285的更多相关文章
- LOJ6277~6285 数列分块入门
Portals 分块需注意的问题 数组大小应为,因为最后一个块可能会超出的范围. 当操作的区间在一个块内时,要特判成暴力修改. 要清楚什么时候应该+tag[t] 数列分块入门 1 给出一个长为的数列, ...
- LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)
#6285. 数列分块入门 9 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2 题目描述 给 ...
- 数列分块入门九题(三):LOJ6283~6285
Preface 最后一题我一直觉得用莫队是最好的. 数列分块入门 7--区间乘法,区间加法,单点询问 还是很简单的吧,比起数列分块入门 7就多了个区间乘. 类似于线段树,由于乘法的优先级高于加法,因此 ...
- 数列分块入门九题(一):LOJ6277~6279
Preface 分块,一个神奇的暴力算法.可以把很多\(O(n^2)\)的数据结构题的暴力优化到常数极小的\(O(n\sqrt n)\).当一些毒瘤题无法用线段树,主席树,平衡树,树状数组...... ...
- [Loj] 数列分块入门 1 - 9
数列分块入门 1 https://loj.ac/problem/6277 区间加 + 单点查询 #include <iostream> #include <cstdio> #i ...
- 数列分块入门九题(二):LOJ6280~6282
Preface 个人感觉这中间的三题是最水的没有之一 数列分块入门 4--区间加法,区间求和 这个也是很多数据结构完爆的题目线段树入门题,但是练分块我们就要写吗 修改还是与之前类似,只不过我们要维护每 ...
- LOJ6285 数列分块入门9(分块)
昨天对着代码看了一晚上 然后今天终于在loj上过了 数列分块入门9题撒花★,°:.☆( ̄▽ ̄)/$:.°★ . 然后相当玄学 块的大小调成\(\sqrt{n}\)会TLE,改成150就过了 啧 然后就 ...
- LOJ 6277:数列分块入门 1(分块入门)
#6277. 数列分块入门 1 内存限制:256 MiB时间限制:100 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论 3 测试数据 题目描述 给出一 ...
- LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)
#6284. 数列分块入门 8 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2 题目描述 给出 ...
随机推荐
- 使用ansible对远程主机上的ssh公钥进行批量分发
使用ansible对远程主机上的ssh公钥进行批量分发或者是删除修改操作 ansible内置了一个authorized_key模块,这个模块很好用,我们使用这个模块可以对远程 主机上的ssh公钥进行批 ...
- android draw9patch工具使用
1.作用 将图片制作android .9图片xxx.9.png xxx.9.jpg xxx.9.gif 这些图片在android上拉伸时,边角不变形,不影响效果. 2.工具位置 Android的S ...
- vs直接IP访问运行项目
找到IIS Express 正在运行的项目应用程序,点击网站,会出现配置路径,找到配置路径,显示隐藏的文件夹 localhost替换成本地IP,重新运行项目,然后就可以直接通过IP访问项目,好处就是便 ...
- C#基础学习5
数组集合
- 【转】Android官方架构项目之MVP + Clean
首先,不了解 Clean 架构的可以看看这个,不过也没关系,阅读本文后你也许会对Clean架构思想有一个认识. 对比MVP项目的结构图,我们发现不同之处是新增的这个Domain Layer这层,来隔离 ...
- iframe 完全跨域自适应高度
1.跨域访问页面, 需要访问后台的页面,通过后台调转 2.跨域自适应宽高 思路:通过相互嵌套,获取跨域页面的高度,通过src传回到本域,通过parent方法设置主页的iframe的高度 index ...
- LC.exe 已退出,代码为-1 问题解决
最近一个c#工程,之前编译正常.后重装系统,安装DevExpress后,编译一直失败,并提示"4>C:\Windows\Microsoft.NET\Framework\v4.0.303 ...
- 1-2 编程基础 GDB程序调试
简介 GDB是GNU发布的一款功能强大的程序调试工具.GDB主要完成下面三个方面的功能: 1.启动被调试程序 2.让被调试的程序在指定的位置停住. 3.当程序被停住时,可以检查程序状态(如变量值). ...
- WPF知识点全攻略00- 目录
知识点目录如下: 1.WPF相对WinFrom的优缺点 2.WPF体系结构 3.XAML 4.XAML页面布局 5.XAML内容控件 6.WPF中的“树” 7.Binding 8.依赖属性 9.附加属 ...
- Lampiao(dirtycow)脏牛漏洞复现
nmap扫描内网80端口发现目标主机 nmap -sP -p 80 192.168.31.0/24 扫描发现目标主机开放22端口.并且 1898端口开放http服务 御剑扫描目录并访问之后发现存 ...