傳送門
由於資料保證最後的答案為非負數,那麼序列就有兩種情況:
1、序列中有兩個或兩個以上非負數。
2、序列中只有乙個非負數。
對於第一種情況,每一次的操作一定是將最大的兩個數相加放入序列中。比如有不降序列:a1
,a2,
a3……
,an−
1,an
,進行多次操作就可以寫出如下的序列: a1
,a2,
a3…a
n−1,
an,a
n−1+
an a
1,a2
,a3…
an−1
,an,
an−1
+an,
an−1
+2an
a1,a2,a
3…an
−1,a
n,an
−1+a
n,an
−1+2
an,2
an−1
+3an
a1,a2,a
3…an
−1,a
n,an
−1+a
n,an
−1+2
an,2
an−1
+3an
,3an
−1+5
an .
..可以看出an
−1和a
n 的係數呈斐波那契數列。那麼我們就需要求斐波那契數列的字首和,這個o(
k)的遞推可以用矩陣快速冪來加速。 [s
n−1f
nfn−
1]∗⎡
⎣⎢11
0011
010⎤
⎦⎥=[
snfn
+1fn
] 對於第二種情況,一定是唯一的乙個非負數數和數列中的最大的負數相加,直到數列中有兩個非負數,再進行第一種操作。
我的方法比較麻煩,用等差數列的求和公式求出負數和非負數相加過程中的和。實際上由於|a
i|<=
100000
,可以直接暴力計算。
#include
#include
#include
#include
using namespace std;
#define ll long long
#define n 100005
#define mod 10000007
int n,p;
struct hpa,unit,mi,ans;
ll a[n],sum,s1,s2,k1,k2;
inline hp cheng(hp a,hp b)
inline hp fast_pow(hp a,int p)
int main()
else
if (p==0)
for (int i=1;i<=3;++i)
for (int j=1;j<=3;++j) unit.a[i][j]=ans.a[i][j]=0;
for (int i=1;i<=3;++i) unit.a[i][i]=1;
a.a[1][1]=a.a[2][1]=a.a[2][2]=a.a[2][3]=a.a[3][2]=1;
mi=fast_pow(a,p-1);
ans.a[1][1]=ans.a[1][2]=ans.a[1][3]=1;
ans=cheng(ans,mi);
k1=ans.a[1][1]; k2=(ans.a[1][1]-1+ans.a[1][2])%mod;
sum=(sum+(s1*k1
%mod+s2*k2
%mod)%mod)%mod;
sum=((sum%mod)+mod)%mod;
printf("%lld\n",sum);
}
1、考慮問題情況要全面。 BZOJ4547 小奇的集合
有乙個大小為n的可重集s,小奇每次操作可以加入乙個數a b a,b均屬於s 求k次操作後它可獲得的s的和的最大值。資料保證這個值為非負數 很顯然,我們每次肯定是取集合中最大的兩個數,那麼我們設這兩個數為 a b,當前的和為 s 顯然有轉移 a b,b a b,s a b s,那麼用矩陣乘法加速即可。...
BZOJ4547 Hdu5171 小奇的集合
給有乙個大小為n的可重集s,每次操作可以加入乙個數a b a,b均屬於s 求k次操作後它可獲得的s的和的最大 值。資料保證這個值為非負數 我們先來看看,因為我們要得到最大的s,所以每次我們都要使得a b最大 首先排除一開始得到的a,b為負數的情況,我們將a b放進s裡,那麼下一次操作就會將a a b...
BZOJ 4548 小奇的糖果
有 n 個彩色糖果在平面上。小奇想在平面上取一條水平的線段,並拾起它上方或下方的所有糖果。求出最多能夠拾 起多少糖果,使得獲得的糖果並不包含所有的顏色。包含多組測試資料,第一行輸入乙個正整數 t 表示測試資料組數。接下來 t 組測試資料,對於每組測試資料,第一行輸入兩個正整數 n k,分別表示點數和...