「CodeChef Dec13 REALSET」 Petya and Sequence 循環卷積

題目大意:

  傳送門c++

  T組詢問。數組

  每組給一個數組,詢問該數組是否循環移位線性無關,輸出YES或NO。spa

題解:

  LCA冬令營有講……然而當時……code

  並不知道如何計算一個數組是否循環移位線性無關……網上也沒有……學校還加了白名單,翻不了牆,看不了wiki(英文看不懂……)。因此這就是我慫題解的理由23333。blog

  題解上說wiki上循環矩陣的行列式等於其DFT後點值乘積。即對於矩陣:get

  

  有:it

  

  顯然若是循環數組的矩陣的軼不爲n的話其行列式必然爲0。class

  因此把數組DFT之後看一下其乘積是否爲0便可。循環

  證實什麼的……留個坑吧。gc

  看到了一個大神打了幾十行……沒看懂在幹什麼……

  LCA說還能夠用分圓多項式,然而並無找到資料。再留個坑吧……

代碼:

  1 #include "bits/stdc++.h"
  2  
  3 using std::swap;
  4  
  5 inline int read () {
  6     int s=0,k=1;char ch=getchar();
  7     while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
  8     while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
  9     return s*k;
 10 }
 11  
 12 typedef long long ll;
 13  
 14 const int N=1e5+10;
 15  
 16 ll mod,g,w[2][N],W[2][N],n,m;
 17  
 18 inline ll gcd (ll a,ll b) {
 19     return b?gcd(b,a%b):a;
 20 }
 21  
 22 inline ll Mult ( ll a,ll b ) {
 23     return ( a*b - (ll)( (long double) a*b/mod )*mod + mod )% mod;
 24 }
 25  
 26 inline ll powmod ( ll a, ll b ) {
 27     ll ret=1;
 28     while (b) {
 29         if (b&1) ret=Mult ( ret, a );
 30         b>>=1,a=Mult ( a, a);
 31     }return ret;
 32 }
 33  
 34 inline int is_prim(ll x) {
 35     for (int i=2;1ll*i*i<=x;++i)
 36         if (x%i==0) return false;
 37     return true;
 38 }
 39  
 40 inline int is_prim_root(ll x,ll y){
 41     for (int i=1;1ll*i*i<y;++i)
 42         if ((y-1)%i==0) {
 43             if (powmod(x,i)==1) return false;
 44             if (powmod(x,(y-1)/i)==1)return false;
 45         }
 46     return true;
 47 }
 48  
 49 inline void init () {
 50     for (m=1;m<=2*n;m<<=1);
 51     ll lcm = n*m/gcd(n,m);
 52     mod = lcm + 1;
 53     for (int i=30;~i;--i)
 54         if (mod + (lcm<<i)<1e3*n) mod+=lcm<<i;
 55     while (mod<1e3*n) mod+=lcm;
 56     while (!is_prim(mod))  mod+=lcm;
 57     for (g=2;;++g) {
 58         int flag=true;
 59         for (int i=2;1ll*i*i<=mod;++i) if ((mod-1)%i==0){
 60             if (powmod(g,i)==1) {flag=false;break;}
 61             if (powmod(g,(mod-1)/i)==1) {flag=false;break;}
 62         }
 63         if (flag) break;
 64     }
 65     
 66     ll w0=powmod(g,(mod-1)/m);
 67     w[0][0]=w[1][0]=1;
 68     int i;
 69     for (i=1;i<m;++i) w[0][i]=Mult(w[0][i-1],w0);
 70     for (i=1;i<m;++i) w[1][i]=w[0][m-i];
 71     w0=powmod(g,(mod-1)/n);
 72     W[0][0]=W[1][0]=1;
 73     for (i=1;i<n;++i) W[0][i]=Mult(W[0][i-1],w0);
 74     for (i=1;i<n;++i) W[1][i]=W[0][n-i];
 75 }
 76  
 77  
 78 inline void NTT(ll *a,int n,int f) {
 79     register int i,j,k,l,t;
 80     for (i=j=0;i^n;++i) {
 81         if (i>j) std::swap(a[i],a[j]);
 82         for (k=n>>1;(j^=k)<k;k>>=1);
 83     }
 84     for (i=1;i<n;i<<=1) 
 85         for (j=0,t=n/(i<<1);j<n;j+=i<<1) 
 86             for (k=l=0;k<i;++k , l+=t ) {
 87                 ll x=a[j+k],y=Mult(a[i+j+k],w[f][l]);
 88                 a[j+k]=x+y;
 89                 a[i+j+k]=x-y;
 90                 if (a[j+k]>=mod) a[j+k]-=mod;
 91                 if (a[i+j+k]<0) a[i+j+k]+=mod;
 92             }
 93     if (f ) {
 94         ll rev=powmod ( n,mod-2 );
 95         for (i=0;i<n;++i) a[i]=Mult(a[i],rev);
 96     }
 97 }
 98  
 99  
100 inline void Bluesteins(ll *a,int f){
101     static ll X[N],Y[N];
102     register int i;
103     for (i=0;i<2*n;++i) Y[2*n-1-i]=W[f][1ll*i*(i-1)/2%n];
104     for (i=2*n;i<m;++i) Y[i]=0;
105     NTT(Y,m,0);
106     for (i=0;i<n;++i) X[i]=Mult(a[i],W[f][ (n-1ll*i*(i-1)/2%n)%n ]);
107     for (i=n;i<m;++i) X[i]=0;
108     NTT(X,m,0);
109     for (i=0;i<m;++i) X[i]=Mult(X[i],Y[i]);
110     NTT(X,m,1);
111     for (i=0;i<n;++i)
112         a[i]=Mult (X[2*n-1-i],W[f][(n-1ll*i*(i-1)/2%n)%n ]);
113     if (f)  {
114         ll rev=powmod(n,mod-2);
115         for (i=0;i<n;++i) a[i]=Mult(a[i],rev);
116     }
117 }
118 
119 ll a[N];
120  
121 int main (int argc, char const* argv[]){    
122     //freopen("Dec13Realset.in","r",stdin);
123     int T=read(),i;
124     while (T-- ){
125         n=read();
126         for (i=0;i<n;++i) a[i]=read();
127         init();
128         Bluesteins(a,0);
129         ll flag=1;
130         for (i=0;i<n;++i) flag=Mult(flag,a[i]);
131         puts(flag?"NO":"YES");
132     }
133     return 0;
134 }
相關文章
相關標籤/搜索