1. 程式人生 > >國慶七連測(二) 模模塔

國慶七連測(二) 模模塔

(這是什麼破標題)

【一句話題意】給定兩個陣列ai和bi,求陣列ci。變換規律為ci=Σj=1iabbi&ThinSpace;mod&ThinSpace;j c_{i}=\Sigma^i_{j=1} \lfloor \frac{a}{b}\rfloor b_{i \,mod\,j} n<=100,000所以ci是123456789 【分析】 這題需要玄學O(nn) O(n\sqrt{n})優化。 玄學打表可得:i/j的值不變時,b的下標成公差為i/j的等差序列(具體原因不明)。當 j小於等於根號i時,暴力計算;另外部分i/j的大小小於等於根號i,如果預處理好公差的等差序列字首和也可以O1求解。 而預處理的複雜度也在O

(nn) O(n\sqrt{n}) 所以總複雜度就在O(nn) O(n\sqrt{n}) 完美卡過。。。。 Code:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1e5+1000;
const int K=330;
const int mod=123456789;
int
a[maxn],b[maxn],c[maxn]; int sum[K][maxn]; int n; int main(){ cin>>n; for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=0;i<n;i++)scanf("%d",&b[i]); for(int i=1;i<K;i++) for(int j=0;j<n;j++){ sum[i][j]=(j>=i?sum[i][j-i]:0)+b[j]; while(sum[i][j]>=mod) sum[i][
j]-=mod; } for(int i=1;i<=n;i++){ for(int j=1;j<=K&&j<=i;j++) c[i]=(c[i]+(LL)a[i/j]*b[i%j])%mod; int r,t; for(int j=K+1;j<=i;j=r+1){ t=i/j,r=i/t; c[i]=(c[i]+(LL)a[t]*(mod+sum[t][i-t*j]-(i>t*(r+1)?sum[t][i-t*(r+1)]:0)))%mod; } } for(int i=1;i<=n;i++) printf("%d\n",c[i]); return 0; }