P3909 異或之積(後綴和)

P3909 異或之積(後綴和)

傳送門

思路:後綴和的巧妙應用。

原式

=6×i=1naij=i+1najk=j+1nak=6\times\sum\limits_{i=1}^n a_i\sum\limits_{j=i+1}^n a_j\sum\limits_{k=j+1}^n a_k

=6×i=1naij=i+1najcj+1,(cj+1=k=j+1nak)=6\times \sum\limits_{i=1}^n a_i\sum\limits_{j=i+1}^n a_jc_{j+1},\quad (c_{j+1}=\sum\limits_{k=j+1}^n a_k)

=6×i=1naibi+1,(bi+1=j=i+1najcj+1)=6\times \sum\limits_{i=1}^n a_ib_{i+1},\quad(b_{i+1}=\sum\limits_{j=i+1}^n a_jc_{j+1})

=6×A1=6\times A_1

時間複雜度:O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
ll a[N],b[N],c[N];
int n; 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]),b[i]=c[i]=a[i];
	}
	for(int i=n;i>=1;i--){
		c[i]=(c[i]+c[i+1])%mod;
		b[i]=(b[i]*c[i+1]+b[i+1])%mod;
		a[i]=(a[i]*b[i+1]+a[i+1])%mod;
	}
	printf("%lld\n",(a[1]*6%mod+mod)%mod);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章