Luogu P1438无聊的序列【线段树/差分】By cellur925
题目大意:维护一个序列,维护区间加等差数列,单点查询的操作。
首先我们肯定是要用线段树来维护了,按照一般的思维局限,我选择了维护序列中的值,但是区间修改的时候由于公差的存在,所以区间修改有些难搞。后来又想分别维护\(k\)和\(d\),但是最终失败了。
正解十分巧妙,维护的是一个差分序列。如何维护?我们把\(l\)位置加上\(k\),把\([l,r)\)的位置加上\(d\),再把\(r+1\)的位置减去\(k+d*(r-l)\)。当查询的时候我们只要做一遍前缀和就好了。
然后??上一个线段树的区间修改+查询的板子就好了==。
#include<cstdio>
#include<algorithm>
#define maxn 100090
using namespace std;
typedef long long ll;
int n,m;
ll k,d,seq[maxn];
struct SegmentTree{
int l,r;
ll val,lazy;
}t[maxn*4];
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(l==r) return ;
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
void update(int p)
{
if(!t[p].lazy||t[p].l==t[p].r) return ;
t[p<<1].lazy+=t[p].lazy;
t[p<<1|1].lazy+=t[p].lazy;
t[p<<1].val+=t[p].lazy*(t[p<<1].r-t[p<<1].l+1);
t[p<<1|1].val+=t[p].lazy*(t[p<<1|1].r-t[p<<1|1].l+1);
t[p].lazy=0;
}
void change(int p,int l,int r,ll x)
{
update(p);
if(t[p].l==l&&t[p].r==r)
{
t[p].val+=1ll*x*(r-l+1);
t[p].lazy+=x;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
if(l>mid) change(p<<1|1,l,r,x);
else if(r<=mid) change(p<<1,l,r,x);
else change(p<<1,l,mid,x),change(p<<1|1,mid+1,r,x);
t[p].val=t[p<<1].val+t[p<<1|1].val;
}
ll ask(int p,int l,int r)
{
update(p);
if(t[p].l==l&&t[p].r==r) return t[p].val;
int mid=(t[p].l+t[p].r)>>1;
if(l>mid) return ask(p<<1|1,l,r);
else if(r<=mid) return ask(p<<1,l,r);
else return ask(p<<1,l,mid)+ask(p<<1|1,mid+1,r);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&seq[i]);
build(1,1,n);
for(int i=1;i<=m;i++)
{
int op=0,p=0;
scanf("%d",&op);
if(op==1)
{
int l=0,r=0;
scanf("%d%d%lld%lld",&l,&r,&k,&d);
change(1,l,l,k);
if(r>l) change(1,l+1,r,d);
if(r!=n) change(1,r+1,r+1,-k-d*(r-l));
}
else if(op==2) scanf("%d",&p),printf("%lld\n",seq[p]+ask(1,1,p));
}
return 0;
}
注意:防止RE,修改的时候在\([l+1,r)\)区间改的时候要注意是不是\(l=r\);以及在\(r+1\)修改的时候判断是不是右区间为\(n\)。
还是思维不要被僵化啊。
Luogu P1438无聊的序列【线段树/差分】By cellur925的更多相关文章
- P1438 无聊的数列 (线段树)
题目链接 Solution 直接维护一个差分的线段树就好了. 其中线段树的节点代表 \(r\) 比 \(l\) 多多少. Code #include<bits/stdc++.h> #def ...
- Luogu P1607 庙会班车【线段树】By cellur925
题目传送门 据说可以用贪心做?算了算了...我都不会贪.... 开始想的是用线段树,先建出一颗空树,然后输进区间操作后就维护最大值,显然开始我忽视了班车的容量以及可以有多组奶牛坐在一起的信息. 我们肯 ...
- [luogu P1438] 无聊的数列
[luogu P1438] 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个 ...
- D - 小Z的加油店 线段树+差分+GCD
D - 小Z的加油店 HYSBZ - 5028 这个题目是一个线段树+差分+GCD 推荐一个差分的博客:https://www.cnblogs.com/cjoierljl/p/8728110.ht ...
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...
- 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树
[题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...
- luogu P2574 XOR的艺术 (线段树)
luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...
- 【原创】洛谷 LUOGU P3373 【模板】线段树2
P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第 ...
- 【原创】洛谷 LUOGU P3372 【模板】线段树1
P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...
随机推荐
- java图形界面设计
1. 基本的java Frame操作. Java的图形界面的类主要包括AWT和Swing.在AWT中图形元素的父类为Component. 继承关系如下:Component->Cont ...
- 算法(Algorithms)第4版 练习 1.3.18
1.3.18 Deletes from the list the node immediately following x.
- python列表推导式的if-else
a=[i for i in range(10) if i%2==0]print(a)a=[i if i%2==0 else 'qi' for i in range(10)]print(a) 结果:[0 ...
- 蓝天白云大草原风景PSD背景素材
蓝天白云大草原风景PSD源文件背景素材,蓝天白云,大草原,风景,背景素材,自然风景,草原景色,绿色清新背景 地址:http://www.huiyi8.com/psd/
- Redis常用数据结构和操作
1.String 存入字符类型 Set name luowen 设置name = luowen 存储 Get name 获取设置好的name的值 Setnx name luowen 设置name键值为 ...
- 查 101.201.62.30 IP信誉方法
查 101.201.62.30 IP信誉方法https://www.virustotal.com/#/ip-address/101.201.62.30https://talosintelligence ...
- 深度学习在gilt应用——用图像相似性搜索引擎来商品推荐和服务属性分类
机器学习起源于神经网络,而深度学习是机器学习的一个快速发展的子领域.最近的一些算法的进步和GPU并行计算的使用,使得基于深度学习的算法可以在围棋和其他的一些实际应用里取得很好的成绩. 时尚产业是深度学 ...
- SpringMVC框架<mvc:default-servlet-handler/>的作用
1.创建一个新工程 Eclipse下新建一个web项目,File>New>Dynamic Web Project 2.添加Jar包 3.配置Web.xml 4.配置 ...
- Jmeter-JDBC Request
1. 新建一个测试计划 2. 新建一个线程组 3. 创建数据库连接 4.配置数据库连接 5.添加JDBC Request 6.添加监听器
- poj-1986 Distance Queries(lca+ST+dfs)
题目链接: Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 11531 Accepted ...