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 题目描述 给出 ...
随机推荐
- strak组件(5):为列表定制预留钩子方法
效果图: 新增函数 def get_list_display(self): 获取页面上应该显示的列,预留的自定义扩展,例如:以后根据用户的不同显示不同的 一.stark组件 stark/servic ...
- Codeforces Round #460 (Div. 2).E 费马小定理+中国剩余定理
E. Congruence Equation time limit per test 3 seconds memory limit per test 256 megabytes input stand ...
- Hive 数据实战
需求 remote_addr 用户IP 1.用于根据地址确认区域 2.用于统计来自同一个(外网)用户的访问数量 time_local 用户访问时间 1.分析用户访问时间段 2.合理安排客服上班时间 r ...
- [bzoj3371][poj2009][Usaco2004 Mar]Moo University - Emergency Pizza Order 定制比萨饼
标题这么长的..真是让感觉人头大脚轻. 贴题面先. Description Moo大学的餐厅必须为$C(1\leq C\leq 1000)$头入学的奶牛新生定制比萨饼.比萨饼可以在比萨小屋订做 ...
- Spring---bean的命名
每个Bean可以有一个或多个 id,我们把第一个 id 称为“标识符”,其余id叫做“别名”,这些id在 IoC 容器中必须唯一. Bean id 的命名约定: 遵循XML命名规范 由字母,数字,下 ...
- Python的类(一)
类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外. ...
- samba server on Mac OS X Lion Server
一般Mac共享通过配置wins,smb即可实现.注意在同一个工作组! 参考:http://computers.tutsplus.com/tutorials/how-to-set-up-an-smb-s ...
- elk-logstash: window下指定jdk目录
\bin\logstash.bat文件中, SETLOCAL的后面,CALL "%SCRIPT_DIR%\setup.bat" 的前面增加一行: @echo off SETLOCA ...
- selenium定位弹出菜单
写selenium脚本,在浏览器定位各种弹出菜单时,有时用工具很难去取菜单的属性,下面说下如何去取: 点开firebug ,切换到“脚本”界面,首先在输入框输入单字母s,待弹出下拉列表后,单击左侧的插 ...
- 抓包工具 - Fiddler - (一)
<转载于 miantest> Fiddler基础知识 Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行工作的,使用的代理地址是:127.0.0.1,端口默认为8888 ...