QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#793466#618. 多项式乘法zhulexuan100 ✓346ms76076kbC++145.8kb2024-11-29 20:13:132024-11-29 20:13:15

Judging History

你现在查看的是最新测评结果

  • [2024-11-29 20:13:15]
  • 评测
  • 测评结果:100
  • 用时:346ms
  • 内存:76076kb
  • [2024-11-29 20:13:13]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf INT_MAX
#define fr(i,l,r) for (i=(l); i<=(r); i++)
#define rfr(i,l,r) for (i=(l); i>=(r); i--)
template<typename T>inline void read(T &n){
    T w=1; n=0; char ch=getchar();
    while (!isdigit(ch) && ch!=EOF){ if (ch=='-') w=-1; ch=getchar(); }
    while (isdigit(ch) && ch!=EOF){ n=(n<<3)+(n<<1)+(ch&15); ch=getchar(); }
    n*=w;
}
template<typename T>inline void write(T x){
    if (x==0){ putchar('0'); return ; }
    T tmp;
    if (x>0) tmp=x;
    else tmp=-x;
    if (x<0) putchar('-');
    char F[105];
    long long cnt=0;
    while (tmp){
        F[++cnt]=tmp%10+48;
        tmp/=10;
    }
    while (cnt) putchar(F[cnt--]);
}
#define Min(x,y) x = min(x,y)
#define Max(x,y) x = max(x,y)
//基础配置=================================================================================
//多项式模板begin--------------------------------------------------------------------------
//多项式里面,长度为n表示有效的数位是0~n-1
const ll Len = 2100005;
const ll mod = 998244353 , G = 3 , iG = (mod+1)/G;
struct poly{
    ll n;//长度,deg(A) = n-1;
    vector<ll> f;
    void size(ll _n){
        n = _n;
        f.resize(n);
    }
};
ll w[Len],to[Len];
inline void add(ll &x,ll y){
    x+=y;
    if (x>=mod) x-=mod;
}
inline ll addd(ll x,ll y){
    x+=y;
    if (x>=mod) x-=mod;
    return x;
}
ll pw(ll x,ll y){
    ll ans = 1;
    while (y){
        if (y&1) ans = ans * x%mod;
        x = x * x%mod;
        y >>= 1;
    }
    return ans;
}
ll inv(ll x){ return pw(x,mod-2); }
poly operator + (poly a,poly b){
    ll n = max(a.n,b.n);
    a.size(n); b.size(n);
    for (ll i=0; i<n; i++) add(a.f[i],b.f[i]);
    return a;
}
poly operator - (poly a,poly b){
    ll n = max(a.n,b.n);
    a.size(n); b.size(n);
    for (ll i=0; i<n; i++) add(a.f[i],mod-b.f[i]);
    return a;
}
poly pol_mul1(poly a,ll b){//乘常数
    for (ll i=0; i<a.n; i++) a.f[i] = a.f[i] * b%mod;
    return a;
}
poly poly_mul2(poly a,poly b){
    ll n = min(a.n,b.n);
    a.size(n);
    for (ll i=0; i<n; i++) a.f[i] = a.f[i] * b.f[i] %mod;
    return a;
}
ll poly_len(ll n){
    ll len;
    for (len=1; len<n; len<<=1);
    return len;
}
void NTT(ll n,poly &a,ll v){
    ll len,i,j;
    fr(i,1,n-1){
        to[i] = to[i>>1]>>1;
        if (i&1) to[i] |= n>>1;
    }
    fr(i,0,n-1)
        if (i<to[i]) swap(a.f[i],a.f[to[i]]);
    for (len=1; len<n; len<<=1){
        ll x,y;
        if (v==1) x = G; else x = iG;
        x = pw(x,(mod-1)/(len*2));
        w[0] = 1;
        fr(i,1,len) w[i] = w[i-1] * x %mod;
        for (i=0; i<n; i+=2*len){
            fr(j,0,len-1){
                x = a.f[i|j]; y = w[j] * a.f[i|j|len] %mod;
                a.f[i|j] = x+y; if (a.f[i|j]>=mod) a.f[i|j] -= mod;
                a.f[i|j|len] = x-y; if (a.f[i|j|len]<0) a.f[i|j|len] += mod;
            }
        }
    }
    if (v==-1){
        ll x = pw(n,mod-2);
        fr(i,0,n-1) a.f[i] = a.f[i] * x %mod;
    }
}
poly operator * (poly a,poly b){//卷积
    ll len = poly_len(a.n+b.n-1);
    a.f.resize(len);
    b.f.resize(len);
    NTT(len,a,1); NTT(len,b,1);
    for (ll i=0; i<len; i++) a.f[i] = a.f[i]*b.f[i]%mod;
    NTT(len,a,-1);
    a.size(a.n+b.n-1);
    return a;
}
poly poly_inv(ll n,poly a){//f * g = 1 ( mod x^n )
    a.size(n);
    poly ans; ans.size(n);
    if (n==1){ ans.f[0] = pw(a.f[0],mod-2); return ans; }
    poly b = a; b.size((n+1)/2);
    b = poly_inv((n+1)/2,b);
    for (ll i=0; i<b.n; i++) ans.f[i] = addd(b.f[i],b.f[i]);
    ll len = poly_len(2*n);
    a.f.resize(len); b.f.resize(len);
    NTT(len,a,1); NTT(len,b,1);
    for (ll i=0; i<len; i++) ( a.f[i] = a.f[i] * b.f[i] %mod * b.f[i] ) %=mod;
    NTT(len,a,-1);
    for (ll i=0; i<n; i++) add( ans.f[i] , mod-a.f[i] );
    return ans;
}
poly poly_reverse(poly a){
    for (ll i=0; i<a.n-i-1; i++) swap(a.f[i],a.f[a.n-i-1]);
    return a;
}
poly operator / (poly a,poly b){//a/b
    poly ans;
    ans = poly_reverse(a) * poly_inv(a.n-b.n+1,poly_reverse(b));
    ans.size(a.n-b.n+1);
    ans = poly_reverse(ans);
    return ans;
}
poly operator % (poly a,poly b){
    poly ans;
    ans = a - a/b * b;
    ans.size(b.n-1);
    return ans;
}
poly poly_dao(poly a){//导数
    for (ll i=0; i<=a.n-2; i++) a.f[i] = a.f[i+1] * (i+1) %mod;
    a.size(a.n-1);
    return a;
}
poly poly_ji(poly a){//积分
    a.size(a.n+1);
    for (ll i=a.n-1; i>0; i--)
        a.f[i] = a.f[i-1] * inv(i) %mod;
    a.f[0] = 0;
    return a;
}
poly poly_ln(ll n,poly a){//ln(a) (mod x^n)
    poly ans = poly_ji( poly_dao(a) * poly_inv(n,a) );
    ans.size(n);
    return ans;
}
poly poly_exp(ll n,poly a){//exp(a) (mod x^n)
    a.size(n);
    poly ans; ans.size(n);
    if (n==1){ ans.f[0] = 1; return ans; }
    poly b = a; b.size((n+1)/2);
    b = poly_exp(b.n,b);
    a.f[0]++;
    ans = b * ( a - poly_ln(n,b) );
    return ans;
}
poly poly_sqrt(ll n,poly a){//sqrt(a) (mod x^n)
    a.size(n);
    poly ans; ans.size(n);
    if (n==1){ ans.f[0] = 1; return ans; }
    poly b = a; b.size((n+1)/2);
    b = poly_sqrt((n+1)/2,b);
    ans = b*b + a;
    b.size(n);
    for (ll i=0; i<b.n; i++) add( b.f[i] , b.f[i] );
    ans = ans * poly_inv(n,b);
    ans.size(n);//这句一定要写上!!!
    return ans;
}
//多项式模板end----------------------------------------------------------------------------
ll n,m;
poly a,b;
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
    ll i,j;
    read(n); read(m);
    a.size(n+1), b.size(m+1);
    fr(i,0,n) read(a.f[i]);
    fr(i,0,m) read(b.f[i]);
    a = a*b;
    fr(i,0,n+m) write(a.f[i]), putchar('\n');
    return 0;
}
//g++ a.cpp -o a -Wall -Wl,--stack=512000000 -std=c++11 -O2

详细


Pretests


Final Tests

Test #1:

score: 20
Accepted
time: 1ms
memory: 5896kb

input:

96 96
600395131 184265451 942971382 534262851 830366882 542271170 294355449 501371170 797809599 964826049 276651245 375755165 662619442 941920605 328216963 507795473 460271147 874920847 818231910 156789488 590591583 732194508 793983630 93566697 836155866 305319153 432040686 621119061 835023373 57138...

output:

683858396
5532883
499734624
910262414
221004044
924081841
392466229
64190174
260661815
939986106
283456690
260629512
990528995
704246427
991946815
236857583
903415172
900324859
938555797
225258152
874945420
516870315
74759441
769850097
353889928
300397164
63689540
115003940
872945378
407694641
91843...

result:

ok 193 numbers

Test #2:

score: 20
Accepted
time: 3ms
memory: 5944kb

input:

4992 4994
471194390 313639917 705341086 119536186 430124603 244978845 185588341 13731324 707132801 88167972 927324568 846658454 523684029 5133605 767200778 502476309 539772401 778154025 266136872 183516351 260704325 49303370 475056182 928574546 740424153 277920667 708439854 746983628 839491869 53579...

output:

700935456
677302967
772159864
479386810
109686665
263919131
29567167
960045078
636326916
585682137
409426717
14510019
441964472
92801447
551536199
216995135
59736203
790078879
55883568
796138076
265361608
66124731
150347029
93682849
205256362
672081205
86396898
573029352
541084997
293480941
90518071...

result:

ok 9987 numbers

Test #3:

score: 20
Accepted
time: 11ms
memory: 6984kb

input:

29995 29992
417238081 53580806 733071257 224121793 786137422 127072245 129083351 988357079 246853229 150935424 596994106 975796660 838029970 619117898 328485797 948485083 574261409 79312345 596346086 489787404 929520168 515647000 211731260 50868568 811515357 428215135 498099163 644485329 802849075 3...

output:

115270920
49832720
758693293
745763567
322999821
510579248
697424729
850661201
678364508
817667211
668544763
136619207
562899653
692811546
351397117
768369036
573254435
891143982
717302438
707939747
41743610
540709722
240732780
931265491
38731999
642520590
630812534
632188732
342954490
225414102
836...

result:

ok 59988 numbers

Test #4:

score: 20
Accepted
time: 38ms
memory: 14952kb

input:

100000 99993
812398607 947396010 797321381 883949986 56052416 586258761 193247973 611124334 773505112 142179482 565466227 140875825 79890768 893500101 553768089 648879319 480419657 915530184 799329430 494818755 793895824 851865180 459534006 259473419 610037701 472768430 868914058 887444584 588850309...

output:

821875273
646409297
701893040
744951544
891720486
338002304
134405948
686576985
653633849
704180950
763960458
160339533
773107048
630019221
467173934
675237413
824356289
394352126
870024535
473719536
246319541
372709664
656104889
677100818
890131281
374587639
160832628
144239351
450760970
646488586
...

result:

ok 199994 numbers

Test #5:

score: 20
Accepted
time: 346ms
memory: 76076kb

input:

999993 999994
388529697 811245378 165909114 295553883 667981275 78502012 400874009 139394758 249494489 4636487 997712665 259780805 431039016 716944209 709300152 356513646 823185021 699568300 650937921 859190797 899514799 785648601 933470757 627225124 349752104 471458923 456404256 48134357 315599086 ...

output:

199012842
735467570
660520906
870291510
102406003
509914017
591503608
692425397
149848591
232605296
411728228
285507919
90090498
682749099
507720817
425946949
937188332
619041823
738654334
153862895
272311969
793838225
260785140
350903642
151151058
631242104
304026658
123734332
23714740
438936743
77...

result:

ok 1999988 numbers