無聊的序列 洛谷p3940

2021-08-10 04:14:20 字數 1652 閱讀 8347

無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題:無聊的數列。。。(k峰:這題不是傻x題嗎)

維護乙個數列,支援兩種操作:

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:

有沒有巧妙的做法?

解法一:線段樹維護差分操作。

#include#define f(i,l,r) for(i=(l);i<=(r);i++)

using namespace std;

const int maxn=100005;

int a[maxn];

int n,m;

int tree[maxn<<2],lazy[maxn<<2];

inline void pushup(int x)

inline void pushdown(int x,int l,int r)

inline void change(int x,int l,int r,int sj,int tj,int d)

// cout<>1;

if(mid>=sj) change(x<<1,l,mid,sj,tj,d);

if(mid+1<=tj) change(x<<1|1,mid+1,r,sj,tj,d);

pushup(x);

}inline int query(int x,int l,int r,int sj,int tj)

if(lazy[x]) pushdown(x,l,r);

int mid=l+r>>1;

if(mid>=sj) res+=query(x<<1,l,mid,sj,tj);

if(mid+1<=tj) res+=query(x<<1|1,mid+1,r,sj,tj);

pushup(x);

return res;

}int main()

f(i,1,m)

else

} else

f(i,r,r)

f(i,bel[l]+1,bel[r]-1) }}

int main()

f(i,1,cnt)

rr[cnt]=n;

f(i,1,m)

else{

cin>>l;

cout<

洛谷P3940 分組

好題 細節題 答案字典序要求最小,所以考慮倒敘列舉,對於當前一組需要盡量多的加東西,因為後面組選的數越多,前面的選擇機會越多 化列舉序列為列舉值域,這是這道題的關鍵 k 1 倒敘列舉到 i 此時只需判斷當前組中的數是否有加 a i 等於完全平方數的 可以 o n 列舉,但顯然可以更優 列舉所有的完全...

洛谷P3940 分組(並查集)(暴力)

首先發現資料限制了只有k 1 k 1k 1和k 2k 2 k 2的情況,而且值域不是很大,或許可以暴力列舉平方根。考慮k 1 k 1k 1的情況,顯然直接列舉平方根,把不能同組出現的數標記一下就行了。注意我們需要最小化分界的字典序,所以實際上是將字尾劃分得盡量長而已,倒著列舉即可。考慮k 2 k 2...

洛谷 P1438 無聊的數列

題目背景 無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題 無聊的數列。k峰 這題不是傻x題嗎 題目描述 維護乙個數列,支援兩種操作 1 1 l r k d 給出乙個長度等於r l 1的等差數列,首項為k,公差為d,並將它對應加到a l a r 的每乙個數上。即...