loj 数列分块入门 5 7 8
5
题意
给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间开方,区间求和。
思路
用\(tag\)记录这一块是否已全为\(1\).
除分块外,还可用 树状数组+并查集(链表) 或者 线段树 做,见 Educational Codeforces Round 37 F。
Code
#include <bits/stdc++.h>
#define maxn 50010
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
typedef long long LL;
int n, blo, a[maxn], sum[maxn], bl[maxn];
bool tag[maxn];
void modify(int l, int r) {
int temp;
F(i, l, min((bl[l]+1)*blo, r+1)) sum[bl[l]] += (temp=sqrt(a[i]))-a[i], a[i] = temp;
if (bl[l]!=bl[r]) F2(i, bl[r]*blo, r) sum[bl[r]] += (temp=sqrt(a[i]))-a[i], a[i] = temp;
F(i, bl[l]+1, bl[r]) {
if (tag[i]) continue;
bool flag = true;
F(j, i*blo, (i+1)*blo) {
sum[i] += (temp=sqrt(a[j]))-a[j], a[j] = temp;
if (temp > 1) flag = false;
}
tag[i] = flag;
}
}
int query(int l, int r) {
int ret = 0;
F(i, l, min((bl[l]+1)*blo, r+1)) ret += a[i];
if (bl[l]!=bl[r]) F2(i, bl[r]*blo, r) ret += a[i];
F(i, bl[l]+1, bl[r]) ret += sum[i];
return ret;
}
int main() {
scanf("%d", &n); blo = sqrt(n);
F(i, 0, n) scanf("%d", &a[i]), bl[i] = i/blo;
int num = (n+blo-1) / blo;
F(i, 0, num-1) {
F(j, i*blo, (i+1)*blo) sum[i] += a[j];
}
F(j, (num-1)*blo, min(num*blo, n+1)) sum[num-1] += a[j];
F(i, 0, n) {
int op, l, r, c;
scanf("%d%d%d%d", &op, &l, &r, &c); --l, --r;
if (op) printf("%d\n", query(l, r));
else modify(l, r);
}
return 0;
}
7
题意
给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间乘法,区间加法,单点询问。
思路
用\(mtag\)记录每个块整体的倍数,用\(atag\)记录每个块整体的增量。
并且约定\(mtag\)优先级更高,即真实值为\(x*mtag+atag\)
对于不完整的块,先将\(tag\)下放,再直接修改元素;
对于完整的块,修改\(tag\):
- \(+c\):即\((x*mtag+atag)+c=x*mtag+(atag+c)\),于是
atag += x; - \(\times c\):即\((x*mtag+atag)*c=x*(mtag*c)+(atag*c)\),于是
atag *= x, mtag *= x
Code
#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define mod 10007
#define maxn 100010
#define maxm 1010
using namespace std;
typedef long long LL;
int n, blo, bl[maxn], a[maxn], mtag[maxm], atag[maxm];
void reset(int p) {
F(i, p*blo, (p+1)*blo) {
(((a[i]*=mtag[p])%=mod)+=atag[p])%=mod;
}
mtag[p] = 1, atag[p] = 0;
}
void work(int op, int l, int r, int c) {
reset(bl[l]);
F(i, l, min(r+1, (bl[l]+1)*blo)) {
if (op) (a[i]*=c)%=mod;
else (a[i]+=c)%=mod;
}
if (bl[l]!=bl[r]) {
reset(bl[r]);
F2(i, bl[r]*blo, r) {
if (op) (a[i]*=c)%=mod;
else (a[i]+=c)%=mod;
}
}
F(i, bl[l]+1, bl[r]) {
if (op) {
(mtag[i]*=c)%=mod;
(atag[i]*=c)%=mod;
}
else (atag[i]+=c)%=mod;
}
}
int main() {
scanf("%d", &n); blo = sqrt(n);
F(i, 0, n) {
scanf("%d", &a[i]);
mtag[bl[i] = i/blo] = 1;
}
int num=(n+blo-1)/blo;
F(i, 0, n) {
int op, l, r, c;
scanf("%d%d%d%d",&op,&l,&r,&c); --l, --r;
if (op==2) printf("%d\n", (a[r]*mtag[bl[r]]%mod+atag[bl[r]])%mod);
else work(op, l, r, c);
}
return 0;
}
8
题意
给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及询问等于一个数\(c\)的元素,并将这个区间的所有元素改为\(c\).
思路
类似上面两题。
用\(tag\)维护这一块是否均为同一个数。
对于不完整的块:先下放\(tag\)后逐个统计修改元素
对于完整的块:直接针对\(tag\)进行统计和修改
Code
#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 100010
#define maxm 1010
using namespace std;
typedef long long LL;
int a[maxn], bl[maxn], n, blo, tag[maxm];
bool flag[maxm];
void reset(int p) {
if (!flag[p]) return;
flag[p] = false;
F(i, p*blo, min(n, (p+1)*blo)) a[i] = tag[p];
}
int query(int l, int r, int c) {
int ret=0;
if (flag[bl[l]]&&tag[bl[l]]==c) ret += min(r+1, (bl[l]+1)*blo)-l;
else {
reset(bl[l]);
F(i, l, min(r+1, (bl[l]+1)*blo)) {
ret += a[i]==c;
a[i] = c;
}
}
if (bl[l]!=bl[r]) {
if (flag[bl[r]]&&tag[bl[r]]==c) ret += r-bl[r]*blo+1;
else {
reset(bl[r]);
F2(i, bl[r]*blo, r) {
ret += a[i]==c;
a[i] = c;
}
}
}
F(i, bl[l]+1, bl[r]) {
if (flag[i]) {
if (tag[i]==c) ret += blo;
}
else {
flag[i] = true;
F(j, i*blo, (i+1)*blo) ret += a[j]==c;
}
tag[i] = c;
}
return ret;
}
int main() {
scanf("%d", &n); blo = sqrt(n);
F(i, 0, n) {
scanf("%d", &a[i]);
bl[i] = i/blo;
}
int num = (n+blo-1)/blo;
F(i, 0, n) {
int l, r, c;
scanf("%d%d%d", &l,&r,&c); --l, --r;
printf("%d\n", query(l, r, c));
}
return 0;
}
loj 数列分块入门 5 7 8的更多相关文章
- [Loj] 数列分块入门 1 - 9
数列分块入门 1 https://loj.ac/problem/6277 区间加 + 单点查询 #include <iostream> #include <cstdio> #i ...
- loj 数列分块入门 6 9(区间众数)
6 题意 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及单点插入,单点询问,数据随机生成. 题解 参考:http://hzwer.com/8053.html 每个块内用一个\(vecto ...
- LOJ 数列分块入门系列
目录 1.区间加+单点查 每个块维护tag,散的暴力改. code: #include<bits/stdc++.h> using namespace std; const int maxn ...
- LOJ 6277:数列分块入门 1(分块入门)
#6277. 数列分块入门 1 内存限制:256 MiB时间限制:100 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论 3 测试数据 题目描述 给出一 ...
- LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)
#6285. 数列分块入门 9 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2 题目描述 给 ...
- LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)
#6284. 数列分块入门 8 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2 题目描述 给出 ...
- LOJ #6283. 数列分块入门 7-分块(区间乘法、区间加法、单点查询)
#6283. 数列分块入门 7 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2 题目描述 给出 ...
- LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)
#6282. 数列分块入门 6 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 1 题目描述 给出 ...
- LOJ #6281. 数列分块入门 5-分块(区间开方、区间求和)
#6281. 数列分块入门 5 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 5 题目描述 给出 ...
随机推荐
- Charles Dickens【查尔斯·狄更斯】
Charles Dickens In 1812, the year Charles Dickens was born, there were 66 novels published in Britai ...
- python 函数function
函数 当代码出现有规律的重复的时候,只写一次函数实现多次使用(调用) 可使用的函数: 自定义函数 内置函数:文档 https://docs.python.org/3/library/function ...
- 「微信小程序免费辅导教程」26,基础内容组件rich-text体验
- 用(bootstrap)Handsontable做表格,手动实现数据排序
商品graph帐票时,用(bootstrap)Handsontable做表格,手动实现数据排序待解决的问题: 若使用控件本身的排序,必须指定colHead,colHead不能被copy,若想表头被co ...
- ceph 存储系统
http://w w w.c s d n 123.com/html/topnews201408/2/4702.htm
- Windows 2003 IIS服务器配置环境(放.net开发的网站)
配置IIS 安装.Net Framework3.5 安装SQL数据库 IIS的配置与安装步骤: 开始->管理工具->管理您的服务器->添加角色->(配置您的服务器向导)下一步- ...
- C编译器MinGW安装、下载及在notepad++中运行C程序
一.C编译器MinGW的下载及安装步骤 打开MinGW官网:http://www.mingw.org/ 图一 图二 图三 图四 图五 图六 系统中配置环境变量: 图七 验证是否安装成功: CMD中运行 ...
- Windows环境下,python webdriver环境搭建
最近刚开始学习selenium,这是我从虫师的<selenium2自动测试实战--基于Python语言>这本书上学到搭建环境的步骤,里面有加上我的一些总结,希望对大家有所帮助! 准备工 ...
- docker 踩坑笔记之 psql: could not connect to server
最近在用docker跑rails,也遇到了一些坑,这里记录一下. 首先build项目: docker-compose build 然后就开始报错了: psql: could not connect t ...
- mysql中查询常用的关键字
最简单的查询: 1 select * from [where ] 1 select column1,column2....from [where] 这里需要注意的是where子句中条件过滤使用到的关键 ...