1. 程式人生 > >[洛谷P1438]無聊的數列

[洛谷P1438]無聊的數列

code == 接下來 uil turn 輸出 define 兩個 read

題目背景

無聊的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]無聊的數列