P1438 无聊的数列

P1438 无聊的数列

题目背景

无聊的YYB总喜欢搞出一些正常人无法搞出的东西。有一天,无聊的YYB想出了一道无聊的题:无聊的数列。。。(K峰:这题不是傻X题吗)

题目描述

维护一个数列{a[i]},支持两种操作:

1、1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上。即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D,

a[L+2]=a[L+2]+K+2D……a[R]=a[R]+K+(R-L)D。

2、2 P:询问序列的第P个数的值a[P]。

输入输出格式

输入格式:

第一行两个整数数n,m,表示数列长度和操作个数。

第二行n个整数,第i个数表示a[i](i=1,2,3…,n)。

接下来的m行,表示m个操作,有两种形式:

1 L R K D

2 P 字母意义见描述(L≤R)。

输出格式:

对于每个询问,输出答案,每个答案占一行。

输入输出样例

输入样例#1:

5 2
1 2 3 4 5
1 2 4 1 2
2 3

输出样例#1:

6

说明

数据规模:

0≤n,m≤100000

|a[i]|,|K|,|D|≤200

Hint:

有没有巧妙的做法?

 1 /*
 2     其实并不是维护一个等差序列
 3     只需要维护l~r区间的首项 k 和公差 d 就好了
 4     l~r 的子区间 x~y 的首项 k‘=k+d*(x-l);
 5     d‘=d;
 6     查询的时候 不要把标记忘了 其实标记不需要下放
 7     但是 这题有毒 我用读入优化 2个TLE
 8     换成scanf结果就AC了
 9 */
10 #include <ctype.h>
11 #include <cstdio>
12
13 const int MAXN=100010;
14
15 struct node {
16     int l,r;
17     int sum;
18     int k,d;
19 };
20 node t[MAXN<<2];
21
22 int n,m,k,d;
23
24 int a[MAXN];
25
26 inline void build_tree(int now,int l,int r) {
27     t[now].l=l,t[now].r=r;
28     if(l==r) {
29         scanf("%d",&t[now].sum);
30         return;
31     }
32     int mid=(l+r)>>1;
33     build_tree(now<<1,l,mid);
34     build_tree(now<<1|1,mid+1,r);
35 }
36
37 void modify(int now,int l,int r) {
38     if(l<=t[now].l&&r>=t[now].r) {
39         t[now].k+=k+d*(t[now].l-l);
40         t[now].d+=d;
41         return;
42     }
43     int mid=(t[now].l+t[now].r)>>1;
44     if(l<=mid) modify(now<<1,l,r);
45     if(r>mid) modify(now<<1|1,l,r);
46 }
47
48 int query(int now,int pos) {
49     if(t[now].l==t[now].r) return t[now].sum+t[now].k;
50     int ans=t[now].k+t[now].d*(pos-t[now].l);
51     int mid=(t[now].l+t[now].r)>>1;
52     if(pos<=mid) return ans+query(now<<1,pos);
53     if(pos>mid) return ans+query(now<<1|1,pos);
54 }
55
56 int hh() {
57     int flag,l,r;
58     scanf("%d%d",&n,&m);
59     build_tree(1,1,n);
60     for(int i=1;i<=m;++i) {
61         scanf("%d",&flag);
62         if(flag==1) {
63             scanf("%d%d%d%d",&l,&r,&k,&d);
64             modify(1,l,r);
65         }
66         else {
67             scanf("%d",&l);
68             printf("%d\n",query(1,l));
69         }
70     }
71 }
72
73 int sb=hh();
74 int main() {;}

代码

时间: 2024-11-05 11:47:50

P1438 无聊的数列的相关文章

[luogu P1438] 无聊的数列

[luogu P1438] 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上.即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D, a[L+2]=a[L+2]+K+2D……a[R]=a[R]+K+(R-

洛谷 P1438 无聊的数列

题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上.即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D, a[L+2]=a[L+2]+K+2D……a[R]=a[R]+K+(R-L)D. 2.2 P:询问序列的第P个数

无聊的数列

题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上.即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D, a[L+2]=a[L+2]+K+2D……a[R]=a[R]+K+(R-L)D. 2.2 P:询问序列的第P个数

无聊的数列【线段树】

题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]},支持两种操作: 1.1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上.即:令a[L]=a[L]+K,a[L+1]=a[L+1]+K+D, a[L+2]=a[L+2]+K+2D--a[R]=a[R]+K+(R-L)D. 2.2 P:询问序列的第P个数

[LuoguP1438]无聊的数列(差分+线段树/树状数组)

\(Link\) \(\mathcal{Description}\) 给你一个数列,要求支持单点查询\(and\)区间加等差数列. \(\mathcal{Solution}\) 哈哈哈哈这个题十分的有意思,至于为什么有意思等会儿再说~ 其实我们观察这两个操作,单点查询--就是那个\(naive\)的单点查询,那么区间加等差数列呢?我们可以思考一下等差数列的性质--存在公差.不妨考虑差分 \(emmm\)发现我好像还没有在博客园里提过差分--那么就整一整吧正好我好久没捯饬这玩意儿了\(qwq\)

luogu1438无聊的数列(区间加等差数列,求一个数的和)

QAQ一道线段树好题 题目大意: 给定一个有n个数的数列,共m种操作,有两种操作 \(1\ l\ r\ k\ d\)表示将\(a[l]\)~\(a[r]\)的数加一个以k为首相,d为公差 \(2\ x\)表示求\(a[x]\)是多少 QwQ又是一道不会的题 暴力修改肯定会T飞 如果可以用线段树进行区间修改呢?? 我们考虑,对于一段区间\([l,r]\),我们只需要记录它的区间的首相和公差,就能将这个标记下传了 QwQ哇,那可以只使用这个线段树进行一个标记下传了(所以没有up函数) 这里展示一下p

Luogu1438 无聊的数列

题目链接:戳我 线段树中差分和前缀和的应用 其实对于加上等差数列的操作我们可以分成这样三步-- update(1,1,n,l,l,k); if(r>l) update(1,1,n,l+1,r,d); if(r!=n) update(1,1,n,r+1,r+1,-(r-l)*d-k); 然后查询的时候1到当前位置的和就是这个数的值啦! 代码如下: #include<iostream> #include<cstdio> #include<algorithm> #inc

做题单

错误 收藏了过多题目 QWQ P1383 高级打字机 P1270 “访问”美术馆 P1481 魔族密码 P1280 尼克的任务 P1271 聚会的快乐 P3631 [APIO2011]方格染色 P1243 排序集合 P2858 [USACO06FEB]奶牛零食Treats for the Cows P3146 [USACO16OPEN]248 P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome P1896 [SCOI2005]互不侵犯 P3154 [CQOI2

线段树--从入门到精通

线段树,强大的数据结构,用处也是比较广的. 首先,我们要明白线段树是个啥? 线段树,线段嘛,有左右端点,那么它当然可以代表一个区间,那么区间上的好多事情都可以用它来搞,比如:区间加,区间乘,区间求和. 首先让我们先看个线段树的模型. 如图,这就是一棵线段树的模型. 圈内的点表示这是第几个点,红色表示这个点表示的区间范围. 每个点和它的左右两个儿子的编号是有一定的关系的: 点N,它的左儿子编号为N$\times$2,右儿子编号为N$\times$2+1. 线段树支持单点修改,区间修改,单点查询,区