QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#426074 | #8717. 骰子 | NaCly_Fish | TL | 0ms | 18332kb | C++14 | 4.5kb | 2024-05-30 20:51:53 | 2024-05-30 20:51:54 |
Judging History
answer
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 262147
#define reg register
#define ll long long
using namespace std;
const int p = 1000000007;
int siz;
int rev[N],rt1[N],rt2[N],rt3[N];
int p1 = 998244353,p2 = 1004535809,p3 = 469762049;
inline int power(int a,int t,int m){
int res = 1;
while(t){
if(t&1) res = (ll)res*a%m;
a = (ll)a*a%m;
t >>= 1;
}
return res;
}
inline void init(int n){
int r,lim = 1;
while(lim<=n) lim <<= 1,++siz;
for(reg int i=1;i!=lim;++i) rev[i] = (rev[i>>1]>>1)|((i&1)<<(siz-1));
rt1[lim>>1] = rt2[lim>>1] = rt3[lim>>1] = 1;
int w1 = power(3,(p1-1)>>siz,p1),w2 = power(3,(p2-1)>>siz,p2),w3 = power(3,(p3-1)>>siz,p3);
for(reg int i=(lim>>1)+1;i!=lim;++i){
rt1[i] = (ll)rt1[i-1]*w1%p1;
rt2[i] = (ll)rt2[i-1]*w2%p2;
rt3[i] = (ll)rt3[i-1]*w3%p3;
}
for(reg int i=(lim>>1)-1;i;--i) rt1[i] = rt1[i<<1],rt2[i] = rt2[i<<1],rt3[i] = rt3[i<<1];
}
inline void dft(int *f,int lim,const int *rt,int p){
static unsigned long long a[N];
reg int x,shift = siz-__builtin_ctz(lim);
for(reg int i=0;i!=lim;++i) a[rev[i]>>shift] = f[i];
for(reg int mid=1;mid!=lim;mid<<=1)
for(reg int j=0;j!=lim;j+=(mid<<1))
for(reg int k=0;k!=mid;++k){
x = a[j|k|mid]*rt[mid|k]%p;
a[j|k|mid] = a[j|k]+p-x;
a[j|k] += x;
}
for(reg int i=0;i!=lim;++i) f[i] = a[i]%p;
}
inline void idft(int *f,int lim,const int *rt,int p){
reverse(f+1,f+lim);
dft(f,lim,rt,p);
int x = p-((p-1)>>__builtin_ctz(lim));
for(reg int i=0;i!=lim;++i) f[i] = (ll)f[i]*x%p;
}
const int o0 = power(p1,p2-2,p2),o1 = power((ll)p1*p2%p3,p3-2,p3);
inline int crt(int a,int b,int c){
ll t = (ll)(b-a+p2) * o0%p2 * p1 + a;
return ((c-t%p3+p3) * o1%p3 * p1%p * p2 + t)%p;
}
inline int getlen(int n){ return 1<<(32-__builtin_clz(n)); }
inline void multiply(const int *f,const int *g,int n,int m,int *r,int len){
static int f1[N],g1[N],f2[N],g2[N],f3[N],g3[N];
memcpy(f1,f,(n+1)<<2),memcpy(g1,g,(m+1)<<2);
memcpy(f2,f,(n+1)<<2),memcpy(g2,g,(m+1)<<2);
memcpy(f3,f,(n+1)<<2),memcpy(g3,g,(m+1)<<2);
int lim = getlen(n+m);
memset(f1+n+1,0,(lim-n)<<2),memset(g1+m+1,0,(lim-m)<<2);
memset(f2+n+1,0,(lim-n)<<2),memset(g2+m+1,0,(lim-m)<<2);
memset(f3+n+1,0,(lim-n)<<2),memset(g3+m+1,0,(lim-m)<<2);
dft(f1,lim,rt1,p1),dft(f2,lim,rt2,p2),dft(f3,lim,rt3,p3);
dft(g1,lim,rt1,p1),dft(g2,lim,rt2,p2),dft(g3,lim,rt3,p3);
for(reg int i=0;i!=lim;++i){
f1[i] = (ll)f1[i]*g1[i]%p1;
f2[i] = (ll)f2[i]*g2[i]%p2;
f3[i] = (ll)f3[i]*g3[i]%p3;
}
idft(f1,lim,rt1,p1),idft(f2,lim,rt2,p2),idft(f3,lim,rt3,p3);
for(reg int i=0;i<=len;++i) r[i] = crt(f1[i],f2[i],f3[i]);
}
inline void inverse(const int *f,int n,int *R){
static int g[N],h[N],st[30];
memset(g,0,getlen(n<<1)<<2);
int top = 0,lim = 1;
while(n){
st[++top] = n;
n >>= 1;
}
g[0] = power(f[0],p-2,p);
while(top--){
n = st[top+1];
while(lim<=(n<<1)) lim <<= 1;
memcpy(h,f,(n+1)<<2);
memset(h+n+1,0,(lim-n)<<2);
multiply(h,g,n,n>>1,h,n);
multiply(h,g,n,n>>1,h,n);
for(reg int i=(n>>1);i<=n;++i) g[i] = ((g[i]+g[i])%p-h[i]+p)%p;
}
memcpy(R,g,(n+1)<<2);
}
int n,m,q;
int b[513],pr[1503][513],ord[1503],invp[1503][513];
int tmp[513];
int main(){
scanf("%d%d%d",&n,&m,&q);
init(m<<1|1);
for(int i=0;i<=m;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
for(int j=0;j<=m;++j){
scanf("%d",&pr[i][j]);
if(pr[i][j]>=p) pr[i][j] -= p;
}
int t = 0;
while(pr[i][t]==0) ++t;
ord[i] = t;
for(int j=0;j<=n;++j) pr[i][j] = pr[i][j+t];
}
for(int i=2;i<=n;++i) multiply(pr[i],pr[i-1],m,m,pr[i],m);
for(int i=1;i<=n;++i){
//for(int j=0;j<=m;++j) printf("%d ",pr[i][j]);
//puts("");
}
for(int i=1;i<=n;++i) inverse(pr[i],m,invp[i]);
invp[0][0] = 1;
for(int i=1;i<=n;++i) ord[i] += ord[i-1];
while(q--){
int l,r;
scanf("%d%d",&l,&r);
multiply(pr[r],invp[l-1],m,m,tmp,m);
int od = ord[r]-ord[l-1];
for(int i=m;i>=od;--i) tmp[i] = tmp[i-od];
for(int i=0;i<od;++i) tmp[i] = 0;
int ans = 0;
for(int i=0;i<=m;++i) ans = (ans + (ll)b[i]*tmp[i])%p;
printf("%d\n",ans);
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 18148kb
input:
3 3 3 4 3 2 1 0 1 0 1000000007 0 500000004 0 500000004 0 0 500000004 500000004 1 1 1 2 1 3
output:
3 1 0
result:
ok 3 number(s): "3 1 0"
Test #2:
score: 0
Accepted
time: 0ms
memory: 18332kb
input:
3 3 6 4 3 2 1 1000000007 0 1 0 1000000007 1 0 0 1000000007 0 1 0 1 1 1 2 1 3 2 2 2 3 3 3
output:
2 1 0 3 1 2
result:
ok 6 numbers
Test #3:
score: 0
Accepted
time: 0ms
memory: 18328kb
input:
1 1 1 604063100 57375033 742299910 257700098 1 1
output:
148903503
result:
ok 1 number(s): "148903503"
Test #4:
score: -100
Time Limit Exceeded
input:
1500 200 600000 253665324 876103781 804024983 929290295 908790466 176299158 528078340 696679927 416465140 509641654 705083449 361711737 250659645 735832780 35321360 383752049 203979021 178832532 785212637 514502839 169840231 65809146 504755349 516829442 382478309 901925498 142312128 782336477 741339...
output:
66394849 858043015 290088512 433850735 16359498 544692508 495705795 390858705 334940115 441003348 589429674 891250455 147055038 949270774 782296292 854444995 608076278 772991067 609961969 3444634 534397763 659524291 384815421 329963211 259265811 214554716 662015873 465616975 355211926 398786302 7484...