题面

这题精,真的精

前言:不要被题目背景和描述误导!


Solution:

题目大意

给定一段序列,请你做到区间修改和区间询问。

区间询问即 在 \(L\) 到 \(R\) 区间内,乘上下标后取模的值在条件范围内的元素的个数

暴力方法

时间不充裕者跳过

一道题目, 正解都是由简单到困难一步一步推导出来的 。我们不如先使用暴力来做。

暴力为了优化一点,我们不妨用 差分 进行区间修改的优化

差分是什么?

比如一次需要你对 \(X\) 到 \(Y\) 区间内的所有数加上 \(K\) ,正常都是for(int i : x~y)a[i]++,之间复杂度明显为 N。

而差分,只需要另外那一个数组,在 \(X\) 位置加上 \(K\) , 在 \(Y + 1\) 位置减去 \(K\) ,到最后询问时累加前缀和即可。

差分数组定义: 差分数组 [ i ] 即 原始数组 [ i ] - 原始数组 [ i - 1 ]

差分模板:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int MAXN = 10000 + 5;//定义常量 int a[MAXN];//原始序列
int b[MAXN];//差分序列 inline int read(){//快速读入
int f = 1, x = 0;
char c = getchar(); while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
} while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
} return f * x;
} int main(){
int n = read();//输入元素个数
for(int i = 1;i <= n; i += 1){//+= 1会比 ++ 更快(某机房巨佬说的)
a[i] = read();
b[i] = a[i] - a[i - 1];//初始化差分数组
} int m = read();//输入操作次数
while(m--){
int x = read(),y = read(),z = read();
//左边界 右边界 修改数量
b[x] += z,b[y + 1] -= z;//差分操作
} for(int i = 1;i <= n; i++){
b[i] += b[i - 1];//累加差分数组(前缀和)
cout<<b[i]<<" ";//输出
} return 0;
}

回归正题

修改操作使用差分进行优化,而查询操作就需要动态暴力枚举完成了。

暴力查询操作代码:

int query(int x,int y){
int num = 0;
ll B[MAXN];//临时用来累加差分数组的数组
memset(B,0,sizeof(B));
for(int i = 1;i <= n + 1; i++){
B[i] = b[i] + B[i - 1];
//cout<<B[i]<<" ";
}
//cout<<"\n";
for(int i = x;i <= y; i++){
ll shit = MOD(B[i] * i);//取模操作需要单独处理负数情况,这里我单独用了一个函数
//cout<<i<<" "<<shit<<"\n";
if(shit >= Min && shit <= Max) num++;
}
return num;
}

我们再认真读一遍题,会发现,前面的 Q 次操作是动态的(由于数组会修改),所以我们

不得不暴力查询。但是后面那只“非三次元仓鼠”的询问时静态的(数组不会变了)。

所以:

我们只要预处理前 i 位有多少个符合要求的元素即可!

正解思路总结:

首先对于前面 Q 次操作,使用差分进行修改,暴力进行查询。后面 \(F\) 次静态查询通过预处理后 O(1) 复杂度即可求出答案。 注意:该题对于long long的要求极其之严格,需要大家注意!

AC代码:

#include<bits/stdc++.h>//潇洒的万能头
#define ll long long//懒人必备
using namespace std; const int MAXN = 80000 + 5;//定义常量 int n,q,Min,Max;//如题所述,Q为操作次数
ll mod;//mod的值
ll b[MAXN];//差分数组
ll a[MAXN];//预处理数组 inline ll read(){//快速读入
ll f = 1, x = 0;
char c = getchar(); while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
} while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
} return f * x;
} ll MOD(ll xxx){//单独处理负数取模
if(xxx > 0)return xxx % mod;
return -1 * ((-xxx) % mod);
} int query(int x,int y){//暴力询问
int num = 0;//累加器
ll B[MAXN];//临时用来累加差分数组的数组
memset(B,0,sizeof(B));
for(int i = 1;i <= n + 1; i++){
B[i] = b[i] + B[i - 1];//累加前缀和
//cout<<B[i]<<" ";
}
//cout<<"\n";
for(int i = x;i <= y; i++){
ll shit = MOD(B[i] * i);
//cout<<i<<" "<<shit<<"\n";
if(shit >= Min && shit <= Max) num++;//合法则累加
}
return num;
} int main(){//开始了
// freopen("dis.out","w",stdout);
n = read(),q = read(),mod = read(),Min = read(),Max = read();//快速读入
for(int i = 1;i <= q; i++){//循环操作次数
char c;
cin>>c;//读入操作
if(c == 'A'){//如果是区间修改
int x = read(),y = read();//读入左边界和右边界
ll z = read();//读入修改的值
b[x] += z,b[y + 1] -= z;//差分数组 O(1) 修改
}
if(c == 'Q'){//如果是询问
int x = read(),y = read();//入左边界和右边界
cout<<query(x,y)<<"\n";//输出答案
}
}
ll F = read();//“非三次元仓鼠”静态操作
for(int i = 1;i <= n + 1; i++){
b[i] += b[i - 1];//先累加差分的前缀和
}
for(int i = 1;i <= n; i++){
ll shit = MOD(b[i] * i);
if(shit >= Min && shit <= Max) a[i]++;//合法则累加
a[i] += a[i - 1];//预处理前缀和
}
while(F--){//循环
int x = read(),y = read();//读入左边界和右边界
cout<<a[y] - a[x - 1]<<"\n";//输出
}
return 0;//end
}

洛谷P3984-数据结构 题解的更多相关文章

  1. [洛谷P3948]数据结构 题解(差分)

    [洛谷P3948]数据结构 Description 最开始的数组每个元素都是0 给出n,opt ,min,max,mod 在int范围内 A: L ,R ,X 表示把[l,R] 这个区间加上X(数组的 ...

  2. 洛谷P3948 数据结构——题解

    题目传送 感觉这道题秀了我一地的智商... 审题没审好,没确定带修改的操作中询问的次数<=1000,且max和min都是事先给好.不变的.想了半天线段树.分块,却忘了最基础的暴力. 写不出题时先 ...

  3. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  4. 洛谷P2827 蚯蚓 题解

    洛谷P2827 蚯蚓 题解 题目描述 本题中,我们将用符号 ⌊c⌋ 表示对 c 向下取整. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现 ...

  5. 洛谷P1816 忠诚 题解

    洛谷P1816 忠诚 题解 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人 ...

  6. [POI 2008&洛谷P3467]PLA-Postering 题解(单调栈)

    [POI 2008&洛谷P3467]PLA-Postering Description Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长 ...

  7. [NOI 2020 Online] 入门组T1 文具采购(洛谷 P6188)题解

    原题传送门 题目部分:(来自于考试题面,经整理) [题目描述] 小明的班上共有 n 元班费,同学们准备使用班费集体购买 3 种物品: 1.圆规,每个 7 元. 2.笔,每支 4 元. 3.笔记本,每本 ...

  8. [CodePlus 2017 11月赛&洛谷P4058]木材 题解(二分答案)

    [CodePlus 2017 11月赛&洛谷P4058]木材 Description 有 n棵树,初始时每棵树的高度为 Hi ,第 i棵树每月都会长高 Ai.现在有个木料长度总量为 S的订单, ...

  9. 洛谷P1189 SEARCH 题解 迭代加深

    题目链接:https://www.luogu.com.cn/problem/P1189 题目大意: 给你一个 \(n \times m\) 的矩阵,其中有一些格子可以走,一些各自不能走,然后有一个点是 ...

  10. 洛谷 P5221 Product 题解

    原题链接 庆祝!第二道数论紫题. 推式子真是太有趣了! \[\prod_{i=1}^n \prod_{j=1}^n \frac{\operatorname{lcm}(i,j)}{\gcd(i,j)} ...

随机推荐

  1. Navicat连接oracle,出现Only compatible with oci version 8.1

    与本地oracle连接的时候,一般没问题,sqlplus和oci都是本地oracle自带的,(设置: 工具->选项->oci) 分别为:     oci:D:\app\pcman\prod ...

  2. Javascript的数据类型(原始类型和引用类型)

    1.ECMAScript3中定义了变量可分为原始值和引用值. 原始值:是保存在栈(stack)中的简单数据段:也就是说他们的值是直接存储在变量访问的位置. 引用值:是保存在堆(heap)中的对象,也就 ...

  3. nginx之http反向代理多台服务器

    Nginx http 反向代理高级应用 是Nginx可以基于ngx_http_upstream_module模块提供服务器分组转发.权重分配.状态监测.调度算法等高级功能. http upstream ...

  4. linux netstat 命令简介

    常用选项: -r, --route 显示路由表 -i, --interfaces 显示接口信息表-s, --statistics 显示网络协议汇总信息 -n, --numeric 不解析域名-p, - ...

  5. shell 命令行参数(getopt和getopts)

    getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...

  6. 干货收藏 | Java 程序员必备的一些流程图

    阅读本文大概需要 6 分钟. 转载自:https://juejin.im/post/5d214639e51d4550bf1ae8df 1.Spring 的生命周期 Spring 作为当前 Java 最 ...

  7. js传对象处理

    JSON.stringify(carlist); 需要先将对象进行处理:如果服务端解析异常,可以先将这个值单独解析一次

  8. 三个面向对象相关的装饰器@property@staticmathod@classmethod

    @property 先看实例: from math import pi class Circle: def __init__(self,r): self.r = r @property def per ...

  9. Vue 与 动态组件 import 的尝试

    <template> <component :is='fuck' :data='data'></component> </template> <s ...

  10. 【C++】C++中的异常解析

    异常是程序在执行期间产生的问题.C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作. 异常提供了一种转移程序控制权的方式.C++ 异常处理涉及到三个关键字:try.catch.throw ...