BZOJ 3119 Book 貪心 數學推導

2021-08-09 23:55:22 字數 1735 閱讀 4700

url:

題目大意:

給定乙個序列v的長度n (n<=1e5), 第乙個元素的值p以及序列中所有元素的和m (m在long long範圍內), 規定對於任意的2<=i<=n, 都有v[i]=v[i-1]+a或v[i]=v[i-1]-b, 同時給定a,b, 確定一組可能的v至並輸出。

思路分析:

為了方便起見,先將b變為輸入數的相反數(即變為乙個負數)。

首先,考慮初始值x造成的影響: 它使得1至n的序列所有元素增加了x, 因此可以將這個值剔除,這樣和變成了m−

np.

其次,考慮第i個元素的值v[i]=v[i-1]+a造成的影響: 它使得i至n的序列中所有元素增加了a,使總和增加了(n

+1−i

)a.

同理可得,若v[i]=v[i-1]+b (b為負數)則使總和增加了(n

+1−i

)b在這裡,我們稱這次賦值對總和產生了(n

+1−i

) 點影響。

顯然,所有的賦值對總和一共產生了∑n

i=2(

n+1−

i)=∑

n−1i

=1i=

12n(

n−1)

點影響。設其中+a產生的影響為x點,+b產生的影響為y點。由剛才的結論得:x+

y=12

n(n−

1) x

a+yb

=m−n

x 解二元一次方程組可得x=

12n(

n−1)

−y y

=12a

n(n−

1)−m

+npa

−b於是只需構造方案即可。這一步比較簡單。可以用貪心來實現。

我們的目標是在1至n得正整數範圍內找到一些互不相同數使得他們的和恰好是x,其餘的數的和恰好是y, 因為x+

y=12

n(n−

1).因此,我們只需選出和為x的部分。考慮到1=

1 2=

2,3=

2+1

4=3+

1,5=

3+2,

6=3+

2+1

7=4+

3,8=

4+3+

1,9=

4+3+

2,10=

4+3+

2+1

...

注:第i行能用的最大的數是i.

因此,我們得到一種貪心策略: 從n開始,從大到小依次選擇,如果剩餘的x能夠選上i就選,並且x-=i, 直至x==0為止,剩餘的就是y.

若為x, 則v[i]=v[i-1]+a; 否則v[i]=v[i-1]+b (b<0)

但由於對總和產生了i點影響的是(n+i-1)號決策,因此輸出時勿忘倒著輸出。

**實現:

(memory: 920kb; time: 376ms; code: 614b)

#include

using

namespace

std;

const

int maxn = 1e5;

bool inc[maxn+2];

int main()

}printf("%lld",cur);

for(long

long i=n-1; i; i--)

return

0;}

BZOJ 3781 小B的詢問

description 小b有乙個序列,包含n個1 k之間的整數。他一共有m個詢問,每個詢問給定乙個區間 l.r 求sigma c i 2 的值,其中i的值從1到k,其中c i 表示數字i在 l.r 中的重複次數。小b請你幫助他回答詢問。題目分析 分塊 include include include...

BZOJ3781 小B的詢問

description 小b有乙個序列,包含n個1 k之間的整數。他一共有m個詢問,每個詢問給定乙個區間 l.r 求 r i lc i 2 i lrc i 2的值,其中i的值從1到k,其中c i 表示數字i在 l.r 中的重複次數。小b請你幫助他回答詢問。input 第一行,三個整數n m k。第二...

BZOJ 3781 小B的詢問

time limit 10 sec memory limit 128 mb submit 643 solved 435 submit status discuss 小b有乙個序列,包含n個1 k之間的整數。他一共有m個詢問,每個詢問給定乙個區間 l.r 求sigma c i 2 的值,其中i的值從1...