秒了
2024-07-23 09:03:00
发布于:广东
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mod 1000000007
int n,k,w[11],ans=0;
int d[11];
int l[500010][11],r[500010][11];
void add(int &x,int y){x=(x+y>=mod?x+y-mod:x+y);}
void dec(int &x,int y){x=(x-y<0?x-y+mod:x-y);}
struct Poly{
int a[11],t;
Poly(){t=0;memset(a,0,sizeof(a));}
void clear(){t=0;memset(a,0,sizeof(a));}
void operator =(Poly &B){
Poly re;re.t=t+B.t;
for(int i=0;i<=t;i++)
for(int j=0;j<=B.t;j++)
add(re.a[i+j],1lla[i]B.a[j]%mod);
this=re;
}
}s[11];
int t_max=1e9;
int calc_round_1(){//暴力求解第一轮
int re=0;
for(int i=1;i<=n;i++){
int prod=1;
for(int j=1;j<=k;j++)
if(w[j]-r[i][j]+l[i][j]>0)
prod=1llprod(w[j]-r[i][j]+l[i][j])%mod;
else {prod=0;break;}
add(re,prod);
}
return re;
}
int calc_round_t_max_and_1(){//暴力求解最后一轮
int re=0;
for(int i=1;i<=n;i++){
int prod=1;
for(int j=1;j<=k;j++){
int p=w[j]-max(r[n][j],r[i][j]+d[j])+min(l[n][j],l[i][j]+d[j])-(t_max+1)abs(d[j]);
if(p>0)prod=1llprodp%mod;
else {prod=0;break;}
}
add(re,prod);
}
return re;
}
int ksm(int x,int y){int re=1;for(;(y&1?re=1llrex%mod:0),y;y>>=1,x=1llxx%mod);return re;}
struct Lagrange{//自然数幂和板子
int fac[20],inv_fac[20];
Lagrange(){}
void init(){
fac[0]=inv_fac[0]=1;
for(int i=1;i<=15;i++)fac[i]=1llfac[i-1]i%mod;
inv_fac[15]=ksm(fac[15],mod-2);
for(int i=14;i>=1;i--)inv_fac[i]=1llinv_fac[i+1](i+1)%mod;
}
int pre[20],suf[20];
int calc(int k,int x){
if(!k)return x+1;
int re=0,sum=0;
if(x<=k+2){
for(int i=0;i<=x;i++)add(re,ksm(i,k));
return re;
}
pre[0]=1;for(int i=1;i<=k+2;i++)pre[i]=1llpre[i-1](x-i)%mod;
suf[k+3]=1;for(int i=k+2;i>=1;i--)suf[i]=1llsuf[i+1](x-i)%mod;
for(int i=1;i<=k+2;i++){
add(sum,ksm(i,k));
(k+2-i&1?dec:add)(re,1llsumpre[i-1]%modsuf[i+1]%mod
inv_fac[i-1]%modinv_fac[k+2-i]%mod);
}
return re;
}
}Lag;
int cd[20];
int main()
{
scanf("%d %d",&n,&k);ans=1;
for(int i=1;i<=k;i++)
scanf("%d",&w[i]),ans=1llansw[i]%mod;
for(int i=1,x,y;i<=n;i++){
scanf("%d %d",&x,&y);
d[x]+=y;
for(int j=1;j<=k;j++)
l[i][j]=min(l[i-1][j],d[j]),
r[i][j]=max(r[i-1][j],d[j]);
}
bool tf=false;//判无解
for(int i=1;i<=k;i++)
if(l[n][i]+r[n][i]>=w[i]||d[i]!=0)tf=true;
if(!tf)return puts("-1"),0;
for(int i=1;i<=k;i++)//求t_max
if(w[i]-r[n][i]+l[n][i]<=0){t_max=-2;break;}
else if(d[i]!=0)t_max=min(t_max,(w[i]-r[n][i]+l[n][i])/abs(d[i])-1);
add(ans,calc_round_1());
if(t_max>-2)add(ans,calc_round_t_max_and_1());
if(t_max>=0){
Lag.init();//预处理自然数幂和
for(int i=0;i<=k;i++)
cd[i]=Lag.calc(i,t_max);
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
s[j].clear();//计算出所有多项式,暴力乘起来
s[j].t=d[j]!=0;
s[j].a[0]=w[j]-max(r[n][j],r[i][j]+d[j])+min(l[n][j],l[i][j]+d[j]);
s[j].a[1]=(mod-abs(d[j]))%mod;
if(j>1)s[j]*=s[j-1];
}
for(int j=0;j<=k;j++)
add(ans,1ll*s[k].a[j]*cd[j]%mod);
}
}
printf("%d",ans);
}
这里空空如也
有帮助,赞一个