首页 > 其他 > 详细

[洛谷P1438]无聊的数列

时间:2018-10-01 22:31:37      阅读:175      评论:0      收藏:0      [点我收藏+]

题目背景

无聊的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)。

输出格式:

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

 

一道裸的线段树硬是让我写出来一堆bug,调了好久,其实很简单,只要在下传标记的右儿子维护好首项的变化即可

代码:

 1 //对每个点的的标记维护首项和公差,都具有可加性直接下传即可
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #define M 100010
 6 #define ls node<<1
 7 #define rs node<<1|1
 8 using namespace std;
 9 int n,m;
10 int a[M],tag1[M<<2],tag2[M<<2];
11 int read()
12 {
13     char ch=getchar(); int x=0,f=1;
14     while(ch>9||ch<0) {if(ch==-)f=-1;ch=getchar();}
15     while(ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
16     return x*f;
17 }
18 
19 void build(int node,int l,int r)
20 {
21     if(l==r) {tag1[node]=a[l];return;}
22     int mid=(l+r)/2;
23     build(ls,l,mid);
24     build(rs,mid+1,r);
25 }
26 
27 void push(int node,int l,int r)
28 {
29     if(tag1[node]!=0||tag2[node]!=0)
30     {
31         int mid=(l+r)/2;
32         tag1[ls]+=tag1[node];
33         tag2[ls]+=tag2[node];
34         tag1[rs]+=(mid-l+1)*tag2[node]+tag1[node];
35         tag2[rs]+=tag2[node];
36         tag1[node]=tag2[node]=0;
37     }
38 }
39 
40 void change(int node,int l,int r,int l1,int r1,int k,int d)
41 {
42     if(l1<=l&&r1>=r) 
43     {
44         tag1[node]+=k+(l-l1)*d;
45         tag2[node]+=d;
46         return;
47     }
48     if(l1>r||r1<l) return;
49     int mid=(l+r)/2; push(node,l,r);
50     change(ls,l,mid,l1,r1,k,d);
51     change(rs,mid+1,r,l1,r1,k,d);
52 }
53 
54 int query(int node,int l,int r,int x)
55 {
56     if(l==r) return tag1[node];
57     int mid=(l+r)/2; push(node,l,r);
58     if(x<=mid) return query(ls,l,mid,x);
59     else return query(rs,mid+1,r,x);
60 }
61 
62 int main()
63 {
64     n=read();m=read();
65     for(int i=1;i<=n;i++) a[i]=read();
66     build(1,1,n);
67     for(int i=1;i<=m;i++)
68     {
69         int opt=read();
70         if(opt==1)
71         {
72             int l=read(),r=read(),k=read(),d=read();
73             change(1,1,n,l,r,k,d);
74         } 
75         else printf("%d\n",query(1,1,n,read()));
76     }
77     return 0;
78 }

 

[洛谷P1438]无聊的数列

原文:https://www.cnblogs.com/Slrslr/p/9735912.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!