51nod 1690 區間求和2

2021-08-31 01:38:54 字數 2642 閱讀 7715

一開始考慮的是對於每個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有多少個奇質數。

取模問題,直接long double,最後取模。

分兩種情況:

1、i +j

<=n

+1

i+j<=n+1

i+j<=n

+1。考慮ai×

aj

a_i\times a_j

ai​×aj

​有多少個,那也就是有多少質數長度的區間中心在i,j

i,ji,

j的中點,稍微寫一寫式子就發現貢獻是ai×

aj×(

si+j

−1−s

∣i−j

∣)

a_i\times a_j\times(s_-s_)

ai​×aj

​×(s

i+j−

1​−s

∣i−j

∣​),顯然可以fft。

2、i +j

>

ni+j>n

i+j>n。

寫一寫式子,發現貢獻是ai×

aj×(

s2×n

−(i+

j)+1

−s∣i

−j∣)

a_i\times a_j\times(s_-s)

ai​×aj

​×(s

2×n−

(i+j

)+1​

−s∣i

−j∣)

。然後愉快的發現只用2

22次fft,於是本題就解決了。

#include

using

namespace std;

#define ll long long

#define ld long double

#define pa pair

const

double pi=

acos(-

1.0)

;const

int maxn=

100010

;const

int inf=

2147483647

;const ll mod=

1000000007ll

;int

read()

while

(ch>=

'0'&&ch<=

'9')x=

(x<<3)

+(x<<1)

+(ch^48)

,ch=

getchar()

;return x*f;

}struct c

}a[maxn<<3]

,b[maxn<<3]

;c operator

+(c a,c b)

c operator

-(c a,c b)

c operator

*(c a,c b)

int bin[maxn<<3]

;void

fft(c *a,

int n,

int o)}}

}int n,a[maxn]

;ll ans=0;

int prime[

10000

],len=

0,s[maxn]

;bool mark[maxn]

;void

pre()}

s[2]=

0;for(

int i=

3;i<=n;i++

)s[i]

+=s[i-1]

;}intmain()

memset

(a,0

,sizeof

(a))

;memset

(b,0

,sizeof

(b))

; a[0]

=b[0]=

c(0,

0);for

(int i=

1;i<=n;i++

)a[i]=c

(a[i],0

),b[i]=c

(a[n-i+1]

,0);

fft(a,t,1)

,fft

(b,t,1)

;for

(int i=

0;i<=t;i++

)a[i]

=a[i]

*b[i]

;fft

(a,t,-1

);for(

int i=

1;i<=

(n<<1)

;i++)if

(!(abs

(i-n-1)

&1))

printf

("%lld"

,ans)

;}

51nod 1690 區間求和2

給出乙個長度為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這個的話,能包含他的區間長度...

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...