51nod 1690 區間求和2

2021-08-19 05:25:06 字數 1889 閱讀 5390

給出乙個長度為n的陣列a。區間[l,r]的值為 ∑r−li=0a[l+i]∗a[r−i]

求所有長度為質數的區間的值的總和。

很容易想到,列舉乙個數對,然後統計他的答案

比如說,我們列舉了乙個數對(i

,j) (i,

j)

那麼他的答案的貢獻會有兩種情況 1.i

+j<=n+

1 i+j

<=n+

1這個的話,能包含他的區間長度是[j

−i+1

,j−i

+1+2

∗(i−

1)] [j−

i+1,

j−i+

1+2∗

(i−1

)]

化簡一下式子可以的得到[j

−i+1

,j+i

−1] [j−

i+1,

j+i−

1]

也就是他的答案的貢獻是a[

i]∗a

[j]∗

(s[i

+j−1

]−s[

j−i]

) a[i

]∗a[

j]∗(

s[i+

j−1]

−s[j

−i])

ss

表示質數個數的字首和

然後這個顯然可以用fft處理

然後對於i+

j>n+

1' role="presentation" style="position: relative;">i+j

>n+

1i+j

>n+

1的情況也是同理

這裡就不寫了

有乙個要注意的地方就是,你要保證(i

,j) (i,

j)

合法,也就是要讓(i

,j) (i,

j)

同奇偶

在計算的時候,我們不把2當作質數

最後單獨算就行

然後取模什麼的不用管。。

最後模就行

用double會炸精度,所以要開long double

code:

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

typedef long double lb;

const lb pi=m_pi;

const ll mod=1e9+7;

const ll n=100005

*10;

struct qq

qq (lb _x,lb _y)

};qq operator + (qq x,qq y)

qq operator - (qq x,qq y)

qq operator * (qq x,qq y)

ll bin[n];

void fft (qq *a,ll n,ll o)}}

}ll n;

ll f[n];

ll pri[n],tot;

bool ok[n];

void prepare ()

}ok[2]=false;

for (ll u=1;u<=n;u++) f[u]=f[u-1]+ok[u];

}ll ans=0;

ll a[n];

qq b[n],c[n];

ll g[n];//儲存所有i+j=k的s[i]*s[j]

void solve ()//統計情況

int main()

51nod 1690 區間求和2

一開始考慮的是對於每個a ia i ai 有哪些a ja j aj 與它相乘,但是這樣做不了。正解是考慮每對 ai aj a i,a j ai a j 的貢獻,然後用fft優化。首先直接把長度為2 22的給算了,然後剩下的都是奇質數長度。預處理s is i si 表示1 11 i ii有多少個奇質數...

51nod 1712 區間求和

解法 這個題首先考慮乙個簡單情況 對於區間 x,y 權值為多少。容易寫出公式 f x y s y s x 1 sum y sum x 1 x 1 sum x 1 y x 1 其中s x 表示 從第乙個元素到第x個元素的 所有有序二元組的和 題目中定義的 sum表示字首和 這裡要求的是所有a x a ...

51nod1680 區間求和(BIT dp)

有n個數,給定乙個k,求所有長度大於等於k的區間中前k大數的總和。這樣就比較簡單相信大家都會,所以此題要求當k 1 n的總和,即求 n k 1 n k 1i 1 nj i k 1 區間前k大和 input 輸入五個數n,a1,a,b,c。a1表示第乙個數,a,b,c用來生成其餘n 1個數。a i a...