#include <bits/stdc++.h>
#define INF 1000000000
#define LINF 1000000000000000000
#define mod 1000000007
#define F first
#define S second
#define ll long long
#define N 300010
using namespace std;
int n,m,a[N],b[N],liml[N],limr[N],f[N<<1],sum[N][3];
vector<int> fac[N],updl[N],updr[N];
void upd(int len)
{
int i,j;
for(i=1;i<=len;i++)
{
for(j=2;j*i+1<=len;j++)
{
int lim=j-1;
if(lim>=m)
{
lim=(1ll*(m+1)*m/2)%mod;
}
else
{
lim=(1ll*(m+m-lim+1)*lim/2)%mod;
}
int l=i*j+1,r=i*j+i;
r=min(r,len);
l=len-l+1,r=len-r+1;
swap(l,r);
f[i]=(f[i]+1ll*lim*((1ll*(l+r)*(r-l+1)/2)%mod))%mod;
}
}
return;
}
void solve(int l,int r)
{
int i,j,mn=1,mx=0;
vector<int> seq;
for(i=l+1;i<=r;i++)
{
seq.push_back(a[i]>a[i-1]);
mn=min(mn,seq.back());
mx=max(mx,seq.back());
}
if(mn>=mx)
{
upd(seq.size());
return;
}
vector<int> pts;
for(i=l+1;i<r;i++)
{
if((a[i]>a[i-1])!=(a[i+1]>a[i]))
{
pts.push_back(i);
}
}
int mid=pts[pts.size()>>1];
solve(l,mid);
solve(mid,r);
int cur=0;
for(i=1;i<=seq.size();i++)
{
updl[i].clear();
updr[i].clear();
}
for(j=mid-1;j>=l;j--)
{
if(j<mid-1&&seq[j-l]==seq[j-l+1])
{
cur++;
}
else
{
cur=1;
}
for(i=0;i<fac[cur-1].size();i++)
{
updl[fac[cur-1][i]].push_back(j);
}
}
cur=0;
for(j=mid;j<r;j++)
{
if(j>mid&&seq[j-l]==seq[j-l-1])
{
cur++;
}
else
{
cur=1;
}
for(i=0;i<fac[cur-1].size();i++)
{
updr[fac[cur-1][i]].push_back(j);
}
}
for(i=1;i<=seq.size();i++)
{
mx=0;
for(j=0;j*i<=seq.size();j++)
{
liml[j]=limr[j]=0;
mx=j;
}
int lst=mid-1;
for(j=0;j<updl[i].size();j++)
{
liml[j]=lst-updl[i][j];
lst=updl[i][j];
}
liml[j]=lst-l+1;
lst=mid;
for(j=0;j<updr[i].size();j++)
{
limr[j]=updr[i][j]-lst;
lst=updr[i][j];
}
limr[j]=r-lst;
sum[0][0]=limr[0],sum[0][1]=0,sum[0][2]=0;
for(j=1;j<=mx;j++)
{
sum[j][0]=(sum[j-1][0]+limr[j])%mod;
sum[j][1]=(sum[j-1][1]+1ll*limr[j]*j)%mod;
sum[j][2]=(sum[j-1][2]+1ll*limr[j]*j*j)%mod;
}
for(j=0;j*i<=seq.size();j++)
{
if(!liml[j])
{
continue;
}
int lo=max(0,m-j+1);
if(lo<=mx)
{
int coef=(sum[mx][0]+mod-(lo==0?0:sum[lo-1][0]))%mod;
coef=(1ll*coef*liml[j])%mod;
coef=(1ll*coef*((1ll*(m+1)*m/2)%mod))%mod;
f[i]=(f[i]+coef)%mod;
}
if(m-j>=0)
{
lo=min(m-j,mx);
int A=m+m+1-j+1,B=(mod+j-1)%mod;
int coef=(sum[lo][0]+mod-(j==0?sum[0][0]:0))%mod;
coef=(1ll*coef*((1ll*A*B)%mod))%mod;
coef=(coef+1ll*(A+mod-B)*(sum[lo][1]+mod-(j==0?sum[0][1]:0)))%mod;
coef=(coef-sum[lo][2]+(j==0?sum[0][2]:0))%mod;
coef=(coef+mod)%mod;
coef=(1ll*coef*liml[j])%mod;
coef=(1ll*coef*(mod+1)/2)%mod;
f[i]=(f[i]+coef)%mod;
}
}
}
return;
}
int main(){
int i,j;
cin>>n>>m;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<m;i++)
{
cin>>b[i];
}
for(i=1;i<=max(n,m);i++)
{
for(j=i;j<=max(n,m);j+=i)
{
fac[j].push_back(i);
}
}
solve(0,n-1);
swap(n,m);
swap(a,b);
solve(0,n-1);
f[0]=(1ll*((1ll*n*(n+1)/2)%mod)*((1ll*m*(m+1)/2)%mod))%mod;
cout<<"0 ";
for(i=0;i<n+m-1;i++)
{
cout<<(f[i]+mod-f[i+1])%mod<<" ";
}
puts("");
return 0;
}
洛谷 P10356 [PA2024] Splatanie ciągów
最新推荐文章于 2024-08-13 14:56:59 发布