• 数论


    int cnt,prime[MAXN+1],mi[MAXN+1],vis[MAXN+1];
    //cnt表示素数个数
    //prime存放每个素数
    //mi存放每个数的最小素数因子
    
    void getprime()
    {
        cnt = 0;
        memset(prime,0,sizeof(prime));
        for(int i = 2;i <= MAXN;i++)
        {
            if(!vis[i])
            {
                prime[++cnt] = i;
                mi[i] = i;
            }
            for(int j = 1;j <= cnt && (long long)i*prime[j] <= MAXN;j++)
            {
                vis[prime[j]*i] = 1;
                mi[prime[j]*i] = prime[j];
                if(!(i%prime[j]))   break;
            }
        }
    }
    
    int cnt2,notprime2[1000005],prime2[1000005];
    //区间l,r之间的素数
    void getprime2(int l,int r)
    {
        cnt2 = 0;
        memset(notprime2,0,sizeof(notprime2));
        if(l < 2)   l = 2;
        for(int i = 1;i <= cnt && (long long)prime[i]*prime[i] <= r;i++)
        {
            int t = l/prime[i];
            if(l%prime[i])  t++;
            if(t == 1)  t = 2;
            for(int j = t;(long long)j*prime[i] <= r;j++)
            {
                if((long long)j*prime[i] >= l)  notprime2[j*prime[i]-l] = 1;
            }
        }
        for(int i = 0;i <= r-l;i++)
        {
            if(!notprime2[i])   prime2[++cnt2] = i+l;
        }
    }
    素数筛

    long long factor[105][2];
    //返回素因子个数
    //factor[i][0]表示第i个素因子,factor[i][1]表示第i个素因子的个数
    int getfac(long long x)
    {
        int cnt = 0;
        for(int i = 1;(long long)prime[i]*prime[i] <= x;i++)
        {
            if(x%prime[i] == 0)
            {
                factor[++cnt][0] = prime[i];
                while(x%prime[i] == 0)
                {
                    factor[cnt][1]++;
                    x /= prime[i];
                }
            }
        }
        if(x != 1)
        {
            factor[++cnt][0] = x;
            factor[cnt][1] = 1;
        }
        return cnt;
    }
    合数分解

    long long qmul(long long a,long long b,long long c)
    {
        long long ans = 0;
        a = a%c;
        b = b%c;
        while(b)
        {
            if(b%2)
            {
                ans += a;
                if(ans > c) ans -= c;
            }
            a = a+a;
            if(a > c)   a -= c;
            b /= 2;
        }
        return ans;
    }
    快速乘

    long long qpower(long long a, long long b, long long c)
    {
        long long ans = 1;
        a = a%c;
        while(b)
        {
            if(b%2)    ans = ans*a%c;
            a = a*a%c;
            b /= 2;
        }
        return ans;
    } 
    快速幂
    string mul(string a,string b)
    {
        int arr[200],len = a.length()+b.length();
        memset(arr,0,sizeof(arr));
        reverse(a.begin(),a.end());
        reverse(b.begin(),b.end());
        for(int i = 0;i < a.length();i++)
        {
            for(int j = 0;j < b.length();j++)   arr[i+j] += (a[i]-'0')*(b[j]-'0');
        }
        for(int i = 0;i < len;i++)
        {
            arr[i+1] += arr[i]/10;
            arr[i] %= 10;
        }
        string ans = string(len,'0');
        for(int i = 0;i < len;i++)  ans[i] += arr[i];
        reverse(ans.begin(),ans.end());
        cout << ans << endl;
        return ans;
    }
    
    string strpow(string x,int b)
    {
        string ans = "1";
        while(b)
        {
            if(b%2) ans = mul(ans,x);
            x = mul(x,x);
            b /= 2;
        }
        return ans;
    }
    string快速幂

    struct matrix
    {
        long long m[2][2];
    };
    
    matrix one = {  1,0,
                    0,1 };
    
    matrix mul(matrix a, matrix b)
    {
        matrix tmp;
        for(int i = 0; i < 2;i++)
        {
            for(int j = 0; j < 2;j++)
            {
                tmp.m[i][j] = 0;
                for(int k = 0; k < 2;k++)   tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD;
            }
        }
        return tmp;
    }
    
    matrix maqower(matrix a,int b)
    {
        matrix ans = one;
        while(b)
        {
            if(b%2) ans = mul(ans,a);
            a = mul(a,a);
            b /= 2;
        }
        return ans;
    }
    矩阵快速幂

    long long qmul(long long a,long long b,long long c)
    {
        long long ans = 0;
        a = a%c;
        b = b%c;
        while(b)
        {
            if(b%2)
            {
                ans += a;
                if(ans > c) ans -= c;
            }
            a = a+a;
            if(a > c)   a -= c;
            b /= 2;
        }
        return ans;
    }
    
    long long qpower(long long a,long long b,long long c)
    {
        long long ans = 1;
        a = a%c;
        while(b)
        {
            if(b%2)    ans = qmul(ans,a,c);
            a = qmul(a,a,c);
            b /= 2;
        }
        return ans;
    }
    
    //用a来检验n是否为素数
    //是素数返回1,不是返回0
    bool check(long long a,long long n,long long x,long long t)
    {
        long long ans = qpower(a,x,n);
        if(ans == 1 || ans == n-1)  return 1;
        while(t--)
        {
            ans = qmul(ans,ans,n);
            if(ans == n-1)  return 1;
        }
        return 0;
    }
    
    //判断n是否为素数
    //是素数返回1,不是返回0
    bool miller_rabin(long long n)
    {
        if(n < 2)   return 0;
        if(n == 2)  return 1;
        if(n%2 == 0)    return 0;
        long long x = n-1;
        long long t = 0;
        while(x%2 == 0)
        {
            x /= 2;
            t++;
        }
        srand(time(0));
        for(int i = 1;i <= 10;i++)
        {
            long long a = rand()%(n-1)+1;
            if(!check(a,n,x,t))  return 0;
        }
        return 1;
    }
    miller_rabin判断素数

    long long factor[105];
    int cnt;
    
    long long gcd(long long a,long long b)
    {
        return b?gcd(b,a%b):a;
    }
    
    long long pollard_rho(long long n,long long c)
    {
        long long i = 1,k = 2;
        srand(time(0));
        long long x = rand()%(n-2)+1,y = x;
        while(1)
        {
            i++;
            x = (qmul(x,x,n)+c)%n;
            long long d = gcd(y-x,n);
            if(1 < d && d < n)  return d;
            if(x == y)  return n;
            if(i == k)
            {
                y = x;
                k *= 2;
            }
        }
    }
    
    //求n的质因数,k设为107
    void findfac(long long n,int k)
    {
        if(n == 1)  return;
        if(miller_rabin(n))
        {
            factor[++cnt] = n;
            return;
        }
        long long p = n;
        int c = k;
        while(p >= n)   p = pollard_rho(p,c--);
        findfac(p,k);
        findfac(n/p,k);
    }
    pollard_rho分解质因数

    LL gcd(LL x,LL y)    //最大公约数
    {
        return y?gcd(y,x%y):x;
    }
    
    LL lcm(LL x,LL y)    //最小公倍数
    {
        return x*y/gcd(x,y);
    }
    gcd、lcm
    //lcm(C(n,0), C(n,1),…, C(n,n)) = lcm(1,2,3,…n+1)/(n+1)
    //计算lcm(1,2,3,…n)
    const int N=100000007;
    int visit[N/32+50];
    unsigned int data[5800000];
    int prime[5800000],np=0;
    
    void Prime()   //筛素数,数组从0开始
    {
        prime[0] = data[0] = 2;
        np = 1;
        for(int i = 3;i < N;i += 2)
        {
            if(!(visit[i/32]&(1<<((i/2)%16))))
            {
                prime[np] = i;
                data[np] = data[np-1]*i;
                np++;
                for(int j = 3*i;j < N;j += 2*i) visit[j/32] |= (1<<((j/2)%16));
            }
        }
    }
    
    long long Deal(int n)
    {
        int p = upper_bound(prime,prime+np,n)-prime-1;
        long long ans = data[p];
        for (int i = 0;i < np && prime[i]*prime[i] <= n;i++)
        {
            int mul = prime[i],tmp = prime[i] * prime[i];  ;
            while (tmp/mul == prime[i] && tmp <= n)
            {
                tmp *= prime[i];
                mul *= prime[i];
            }
            ans = ans*(mul/prime[i])%MOD;
        }
        return ans;
    }
    lcm(1,2,3,…n)

    欧拉函数:小于N且与N互质的数的个数(包括1)。

    对于一个正整数N的素数幂分解N = P1^q1*P2^q2*...*Pn^qn。

    φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn)。

    //分解质因数
    int euler(int n)
    {
        int ans = n;
        for(int i = 1;i <= cnt;i++) ans = ans/factor[i][0]*(factor[i][0]-1);
    }
    
    long long euler(long long n)  
    {  
        long long ans = 1;   
        for(int i = 2;(long long)i*i <= n;i++)  
        {  
            if(n%i == 0)  
            {  
                n /= i;  
                ans *= i-1;  
                while(n%i == 0)  
                {  
                    n /= i;  
                    ans *= i;  
                }  
            }  
        }  
        if(n > 1)     ans *= n-1;
        return ans;  
    }
    单个欧拉函数
    int cnt,phi[N+10],prime[N+10],vis[N+10];
    
    //同时得到欧拉函数和素数表
    void geteuler()
    {
        memset(vis,0,sizeof(vis));
        phi[1] = 1;
        cnt = 0;
        for(int i = 2;i <= N;i++)
        {
            if(!vis[i])
            {
                prime[++cnt] = i;
                phi[i] = i-1;
            }
            for(int j = 1;j <= cnt;j++)
            {
                if((long long)i*prime[j] > N)   break;
                vis[i*prime[j]] = 1;
                if(i%prime[j] == 0)
                {
                    phi[i*prime[j]] = phi[i]*prime[j];
                    break;
                }
                else    phi[i*prime[j]] = phi[i]*(prime[j]-1);
            }
        }
    }
    线性筛

    lucas定理:

    A、B是非负整数,p是质数。AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]。
    则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0])  modp同余。

    即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p) 。

    //用与n,m很大,MOD不是很大的情况
    long long qmod(long long a,long long b,long long c)
    {
        long long ans = 1;
        a = a%c;
        while(b)
        {
            if(b%2)  ans = (ans*a)%c;
            a = (a*a)%c;
            b /= 2;
        }
        return ans;
    }
    
    long long c(long long m,long long n)
    {
        if(m < n)   return 0;
        if(m == n)  return 1;
        if(n > m-n) n = m-n;
        long long mm = 1,nn = 1;
        for(long long i = 0;i < n;i++)
        {
            mm = mm*(m-i)%MOD;
            nn = nn*(n-i)%MOD;
        }
        return mm*qmod(nn,MOD-2,MOD)%MOD;
    }
    
    long long lucas(long long m,long long n)
    {
        long long ans = 1;
        while(m && n && ans)
        {
            ans = ans%MOD*c(m%MOD,n%MOD)%MOD;
            n /= MOD;
            m /= MOD;
        }
        return ans;
    }
    lucas
    long long inv(long long a,long long MOD)
    {
        if(!a)  return 0;
        long long b = MOD,x = 0,y = 0;
        e_gcd(a,b,x,y);
        x = ((x%b)+b)%b;
        if(!x)  x += b;
        return x;
    }
    
    long long mul(long long n,long long pi,long long pk)
    {
        if(!n)  return 1;
        long long ans=1;
        for(long long i = 2;i <= pk;i++)
        {
            if(i%pi)    ans = ans*i%pk;
        }
        ans = qpower(ans,n/pk,pk);
        for(long long i = 2;i <= n%pk;i++)
        {
            if(i%pi)    ans = ans*i%pk;
        }
        return ans*mul(n/pi,pi,pk)%pk;
    }
    
    long long C(long long n,long long m,long long MOD,long long pi,long long pk)
    {
        if(m > n)   return 0;
        long long a = mul(n,pi,pk),b = mul(m,pi,pk),c = mul(n-m,pi,pk),k = 0,ans = 0;
        for(long long i = n;i;i /= pi)  k += i/pi;
        for(long long i = m;i;i /= pi)  k -= i/pi;
        for(long long i = n-m;i;i /= pi)    k -= i/pi;
        ans = a*inv(b,pk)%pk*inv(c,pk)%pk*qpower(pi,k,pk)%pk;
        return ans*(MOD/pk)%MOD*inv(MOD/pk,pk)%MOD;
    }
    
    
    long long lucas(long long n,long long m,long long MOD)
    {
        long long ans = 0,x = MOD;
        for(long long i = 2;i*i <= x;i++)
        {
            if(x%i == 0)
            {
                long long t = 1;
                while(x%i == 0)
                {
                    t *= i;
                    x /= i;
                }
                ans = (ans+C(n,m,MOD,i,t))%MOD;
            }
        }
        if(x > 1)   ans = (ans+C(n,m,MOD,x,x))%MOD;
        return ans;
    }
    扩展lucas(模合数)

    费马小定理:假如p是素数,且a与p互质,那么a^(p-1) = 1 (mod p)。

    费马大定理:当整数n>2时,关于 x,y,z的方程x^n+y^n=z^n没有正整数解。

    欧拉定理:若n,a为正整数,且n,a互质,则:a^(phi(n)) = 1(mod n)

                      可得a^b%p = a^(b%phi(p))%p

    另外,a,b不互质且b<phi(n)时,有 a^b%p = a^(b%phi(p)+phi(p))%p


    逆元:ax = 1(mod m)的x值(0 < a < m)。

    当p是质数的时候 a/x mod p == a*x^(p-2) mod p 。

    当p不是质数的时候a/x mod p == a*x^(phi(p)-1) mod p。

    //a,m互质
    long long inv(long long a,long long m)
    {
        return qmod(a,m-2,m);
    }
    逆元1
    //a < m且a,m互质
    long long inv(long long a,long long m)
    {
        if(a == 1)  return 1;
        return inv(m%a,m)*(m-m/a)%m;
    }
    逆元2
    //a,m互质
    //扩展欧几里德
    long long e_gcd(long long a,long long b,long long &x,long long &y)
    {
        if(!b)
        {
            x = 1;
            y = 0;
            return a;
        }
        long long d = e_gcd(b,a%b,y,x);
        y -= a/b*x;
        return d;
    }
    
    long long inv(long long a,long long m)
    {
        long long x,y;
        long long gcd = e_gcd(a,m,x,y);
        if(gcd == 1)    return (x%m+m)%m;
        return -1;
    }
    逆元3

    //求解方程组x%m = a,x的最小值
    //无解返回-1
    long long e_gcd(long long a,long long b,long long &x,long long &y)
    {
        if(!b)
        {
            x = 1;
            y = 0;
            return a;
        }
        long long d = e_gcd(b,a%b,y,x);
        y -= a/b*x;
        return d;
    }
    
    long long solve(long long *m,long long *a,long long n)
    {
        long long M = m[1],A = a[1],x,y;
        for(int i = 2;i <= n;i++)
        {
            long long d = e_gcd(M,m[i],x,y);
            if((a[i]-A)%d)  return -1;
            x = (a[i]-A)/d*x%(m[i]/d);
            A += x*M;
            M = M/d*m[i];
            A %= M;
        }
        if(A < 0)   A += M;
        return A;
    }
    中国剩余定理

    //浮点型只有唯一解时可计算
    //返回0表示无解
    #define eps 1e-9
    double a[N][N],x[N];        //左边矩阵和右边值,结果存在x数组内
    int Gauss(int equ,int var)  //方程个数和未知数个数
    {
        for(int row = 0,col = 0;col < var&&row < equ;col++,row++)
        {
            int max_r=row;
            for(int i = row+1;i < equ;i++)
            {
                if(fabs(a[i][col])-fabs(a[max_r][col]) > eps)   max_r=i;
            }
            if(fabs(a[max_r][col]) < eps)   return 0;
            if(max_r != row)
            {
                for(int j = 0;j <= var;j++) swap(a[row][j],a[max_r][j]);
            }
            for(int i = row+1;i < equ;i++)
            {
                if(fabs(a[i][col]) < eps)   continue;
                double t = -a[i][col]/a[row][col];
                for(int j = col;j <= var;j++)   a[i][j] += t*a[row][j];
            }
        }
        for(int i = var-1;i >= 0;i--)   //计算唯一解。
        {
            double t = 0;
            for(int j = i+1;j < var;j++)    t += a[i][j]*x[j];
            x[i] = (a[i][var]-t)/a[i][i];
        }
        return 1;
    }
    浮点数高斯消元
    #include<bits/stdc++.h>
    using namespace std;
    
    //POJ1681
    //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
    int equ,var;
    int a[250][250];    //增广矩阵
    int x[250];         //解集
    int free_x[250];    //标记是否不确定的变元
    int free_num;       //不确定变元个数
    int n;
    char s[30];
    //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数)
    void init()
    {
        memset(a,0,sizeof(a));
        memset(x,0,sizeof(x));
        equ = n*n;
        var = n*n;
        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j < n;j++)
            {
                int t = i*n+j;
                a[t][t] = 1;
                if(i > 0)   a[(i-1)*n+j][t] = 1;
                if(i < n-1) a[(i+1)*n+j][t] = 1;
                if(j > 0)   a[i*n+j-1][t] = 1;
                if(j < n-1) a[i*n+j+1][t] = 1;
            }
        }
    }
    
    void Debug()
    {
        for(int i = 0;i < equ;i++)
        {
            for(int j = 0;j < var+1;j++)  cout << a[i][j] << " ";
            cout << endl;
        }
        cout << endl;
    }
    
    int Gauss()
    {
        int max_r,col,k;
        free_num = 0;
        for(k = 0,col = 0;k < equ && col < var;k++,col++)
        {
            max_r = k;
            for(int i = k+1;i < equ;i++)
            {
                if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i;
            }
            if(max_r != k)
            {
                for(int i = col;i < var+1;i++)  swap(a[k][i],a[max_r][i]);
            }
            if(a[k][col] == 0)
            {
                k--;
                free_x[free_num++] = col;
                continue;
            }
            for(int i = k+1;i < equ;i++)
            {
                if(a[i][col] == 0)  continue;
                for(int j = col;j < var+1;j++)  a[i][j] ^= a[k][j];
            }
        }
        for(int i = k;i < equ;i++)
        {
            if(a[i][col] != 0)  return -1;
        }
        return var-k;
    }
    
    void solve()
    {
        int t = Gauss();
        if(t == -1) printf("inf
    ");
        else
        {
            int ans = INT_MAX,tot = (1<<t);
            for(int i = 0;i < tot;i++)
            {
                int cnt = 0;
                for(int j = 0;j < t;j++)
                {
                    if(i&(1<<j))
                    {
                        x[free_x[j]] = 1;
                        cnt++;
                    }
                    else    x[free_x[j]] = 0;
                }
                for(int j = var-t-1;j >= 0;j--)
                {
                    int t = a[j][var];
                    for(int k = j+1;k < var;k++)
                    {
                        if(a[j][k]) t ^= x[k];
                    }
                    x[j] = t;
                    cnt += x[j];
                }
                ans = min(ans,cnt);
            }
            printf("%d
    ",ans);
        }
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            init();
            for(int i = 0;i < n;i++)
            {
                scanf("%s",s);
                for(int j = 0;j < n;j++)
                {
                    if(s[j] == 'y') a[i*n+j][n*n] = 0;
                    else    a[i*n+j][n*n] = 1;
                }
            }
            solve();
        }
        return 0;
    }
    01异或高斯消元
    int a[MAXN][MAXN];  //增广矩阵
    int x[MAXN];        //解集
    bool free_x[MAXN];  //标记是否是不确定的变元
    
    int gcd(int a,int b)
    {
        return b?gcd(b,a%b):a;
    }
    int lcm(int a,int b)
    {
        return a/gcd(a,b)*b;
    }
    
    //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数)
    //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
    int Gauss(int equ,int var)
    {
        int i,j,k;
        int max_r;// 当前这列绝对值最大的行.
        int col;//当前处理的列
        int ta,tb;
        int LCM;
        int temp;
        int free_x_num;
        int free_index;
        for(int i = 0;i <= var;i++)
        {
            x[i]=0;
            free_x[i]=true;
        }
        col=0;
        for(k = 0;k < equ && col < var;k++,col++)
        {
            max_r=k;
            for(i = k+1;i < equ;i++)
            {
                if(abs(a[i][col]) > abs(a[max_r][col])) max_r=i;
            }
            if(max_r != k)
            {
                for(j = k;j < var+1;j++)    swap(a[k][j],a[max_r][j]);
            }
            if(a[k][col] == 0)
            {
                k--;
                continue;
            }
            for(i = k+1;i < equ;i++)
            {
                if(a[i][col] != 0)
                {
                    LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                    ta = LCM/abs(a[i][col]);
                    tb = LCM/abs(a[k][col]);
                    if(a[i][col]*a[k][col] < 0) tb = -tb;
                    for(j = col;j < var+1;j++)
                    {
                        a[i][j] = ((a[i][j]*ta-a[k][j]*tb)%7+7)%7;
                    }
                }
            }
        }
        for(i = k; i < equ; i++)
        {
            if (a[i][col] != 0) return -1;
        }
        if(k < var)
        {
            for(i = k-1;i >= 0;i--)
            {
                free_x_num = 0;
                for(j = 0;j < var;j++)
                {
                    if (a[i][j] != 0 && free_x[j])  free_x_num++,free_index = j;
                }
                if(free_x_num > 1)  continue;
                temp = a[i][var];
                for(j = 0;j < var;j++)
                {
                    if(a[i][j] != 0 && j != free_index) temp -= a[i][j]*x[j]%7;
                    temp = (temp%7+7)%7;
                }
                x[free_index] = (temp/a[i][free_index])%7;
                free_x[free_index] = 0;
            }
            return var-k;
        }
        for(i = var-1;i >= 0;i--)
        {
            temp = a[i][var];
            for (j = i + 1;j < var;j++)
            {
                if(a[i][j] != 0)    temp -= a[i][j]*x[j];
                temp = (temp%7+7)%7;
            }
            while(temp%a[i][i] != 0)    temp += 7;
            x[i] =(temp/a[i][i])%7;
        }
        return 0;
    }
    同余方程组高斯消元

    #include<bits/stdc++.h>
    #define N 262145
    #define PI acos(-1)
    using namespace std;
    
    typedef complex<double> C;
    int n,m;
    C a[N],b[N];
    
    int gi()
    {
        int res = 0,fh = 1;
        char ch = getchar();
        while((ch > '9' || ch < '0') && ch != '-')  ch = getchar();
        if(ch == '-')
        {
            fh=-1;
            ch=getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            res = res*10+ch-'0';
            ch=getchar();
        }
        return fh*res;
    }
    
    void fft(C *a,int n,int f)
    {
        if(n == 1)  return;
        C wn(cos(2.0*PI/n),sin(f*2.0*PI/n)),w(1,0),t,a0[n>>1],a1[n>>1];
        for(int i = 0;i < n>>1;i++)
        {
            a0[i] = a[i<<1];
            a1[i] = a[i<<1|1];
        }
        fft(a0,n>>1,f);
        fft(a1,n>>1,f);
        for(int i = 0;i < n>>1;i++,w *= wn)
        {
            t = w*a1[i];
            a[i] = a0[i]+t;
            a[i+(n>>1)] = a0[i]-t;
        }
    }
    int main()
    {
        n = gi();
        m = gi();
        for(int i = 0;i <= n;i++)   a[i]=gi();
        for(int i = 0;i <= m;i++)   b[i]=gi();
        m += n;
        for(n = 1;n <= m;n *= 2);
        fft(a,n,1);
        fft(b,n,1);
        for(int i = 0;i <= n;i++)   a[i] *= b[i];
        fft(a,n,-1);
        for(int i = 0;i <= m;i++)   printf("%d ",int(a[i].real()/n+0.5));
        return 0;
    }
    FFT递归
    #include<bits/stdc++.h>
    #define N 262145
    #define PI acos(-1)
    using namespace std;
    
    typedef complex<double> C;
    int n,m,L,R[N];
    C a[N],b[N];
    
    int gi()
    {
        int res = 0,fh = 1;
        char ch = getchar();
        while((ch > '9' || ch < '0') && ch != '-')  ch = getchar();
        if(ch == '-')
        {
            fh=-1;
            ch=getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            res = res*10+ch-'0';
            ch=getchar();
        }
        return fh*res;
    }
    
    
    void fft(C *a,int f)
    {
        for(int i = 0;i < n;i++)
        {
            if(i < R[i])    swap(a[i],a[R[i]]);
        }
        for(int i = 1;i < n;i *= 2)
        {
            C wn(cos(PI/i),sin(f*PI/i)),x,y;
            for(int j = 0;j < n;j += i<<1)
            {
                C w(1,0);
                for(int k = 0;k < i;k++,w *= wn)
                {
                    x = a[j+k];
                    y = w*a[j+i+k];
                    a[j+k] = x+y;
                    a[j+i+k] = x-y;
                }
            }
        }
    }
    
    int main()
    {
        n = gi();
        m = gi();
        for(int i = 0;i <= n;i++)   a[i] = gi();
        for(int i = 0;i <= m;i++)   b[i] = gi();
        m += n;
        for(n = 1;n <= m;n *= 2)    L++;
        for(int i = 0;i < n;i++)    R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));
        fft(a,1);
        fft(b,1);
        for(int i = 0;i <= n;i++)   a[i] *= b[i];
        fft(a,-1);
        for(int i = 0;i <= m;i++)   printf("%d ",int(a[i].real()/n+0.5));
        return 0;
    }
    FFT非递归

    //需要getprime,qpower,getfac,先调用getprime
    //计算1+p+p^2+````+p^n
    long long sum(long long p,long long n)
    {
        if(p == 0)  return 0;
        if(n == 0)  return 1;
        if(n%2) return (1+qpower(p,n/2+1,MOD))%MOD*sum(p,n/2)%MOD;
        else    return ((1+qpower(p,n/2+1,MOD))%MOD*sum(p,n/2-1)+qpower(p,n/2,MOD)%MOD)%MOD;
    }
    
    //求a^b的约数和对MOD取模
    long long solve(long long a,long long b)
    {
        int cnt = getfac(a);
        long long ans = 1;
        for(int i = 1;i <= cnt;i++)
        {
            ans *= sum(factor[i][0],b*factor[i][1])%MOD;
            ans %= MOD;
        }
        return ans;
    }
    约数和定理

    莫比乌斯反演:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 100000;
    bool check[MAXN+5];
    int prime[MAXN+5],mu[MAXN+5],sum[MAXN+5];
    
    //求莫比乌斯函数
    void Moblus()
    {
        memset(check,0,sizeof(check));
        mu[1] = 1;
        int cnt = 0;
        for(int i = 2;i <= MAXN;i++)
        {
            if(!check[i])
            {
                prime[cnt++] = i;
                mu[i] = -1;
            }
            for(int j = 0;j < cnt && i*prime[j] <= MAXN;j++)
            {
                check[i*prime[j]] = 1;
                if(i%prime[j] == 0)
                {
                    mu[i*prime[j]] = 0;
                    break;
                }
                else    mu[i*prime[j]] = -mu[i];
            }
        }
        sum[0] = 0;
        for(int i = 1;i <= MAXN;i++)    sum[i] = sum[i-1]+mu[i];
    }
    
    //求[1,n],[1,m]内互质的数的对数
    int solve(int n,int m)
    {
        int ans = 0;
        if(n > m)   swap(n,m);
        for(int i = 1,last;i <= n;i = last+1)
        {
            last = min(n/(n/i),m/(m/i));
            ans += (sum[last]-sum[i-1])*(n/i)*(m/i);
        }
        return ans;
    }
    
    int main()
    {
        Moblus();
        int a,b,c,d,k,T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
            a--;
            c--;
            a /= k;
            b /= k;
            c /= k;
            d /= k;
            printf("%d
    ",solve(b,d)-solve(a,d)-solve(b,c)+solve(a,c));
        }
    
    }
    莫比乌斯反演

    #include<bits/stdc++.h>
    using namespace std;
    
    int gcd(int a, int b )
    {
        return b == 0?a:gcd(b,a%b);
    }
    
    long long qpower(long long a, long long b, long long c)
    {
        long long ans = 1;
        a = a%c;
        while(b)
        {
            if(b%2)    ans = ans*a%c;
            a = a*a%c;
            b /= 2;
        }
        return ans;
    }
    
    long long e_gcd(long long a,long long b,long long &x,long long &y)
    {
        if(!b)
        {
            x = 1;
            y = 0;
            return a;
        }
        long long d = e_gcd(b,a%b,y,x);
        y -= a/b*x;
        return d;
    }
    
    int Inval(int a,int b,int n)
    {
        long long x, y, e;
        e_gcd(a,n,x,y);
        e = (long long)x*b%n;
        return e < 0?e+n:e;
    }
    
    //求A^x = B(mod C)(C可以为非素数)
    int BSGS(int A,int B,int C)
    {
        map<int,int> H;
        long long buf = 1%C,D = buf,K;
        int d = 0,tmp;
        for (int i = 0;i <= 100;buf = buf*A%C,i++)
        if(buf == B)    return i;
        while((tmp = gcd(A,C)) != 1)
        {
            if(B % gcd(A,C)!= 0)    return -1;
            d++;
            C /= tmp;
            B /= tmp;
            D =D*A/tmp%C;
        }
        H.clear();
        int M = (int)ceil(sqrt(C));
        buf = 1%C;
        for(int i = 0;i <= M;buf = buf*A%C,i++)
        {
            if(H.find((int)buf) == H.end()) H[(int)buf] = i;
        }
        K = qpower(A,M,C);
        for(int i = 0;i <= M;D = D*K%C,i++)
        {
            tmp = Inval((int)D,B,C);
            if(tmp >= 0 && H.find(tmp) != H.end())  return i*M+H[tmp]+d;
        }
        return -1;
    }
    BSGS

    const double eps = 1e-6;
    // 三点simpson法。这里要求F是一个全局函数
    double simpson(double a,double b)
    {
        double c = a+(b-a)/2;
        return (F(a)+4*F(c)+F(b))*(b-a)/6;
    }
    // 自适应Simpson公式(递归过程)。已知整个区间[a,b]上的三点simpson值A
    double asr(double a,double b,double eps,double A)
    {
        double c = a+(b-a)/2;
        double L = simpson(a,c),R = simpson(c,b);
        if(fabs(A-L-R) <= 15*eps)   return L+R+(A-L-R)/15;
        return asr(a,c,eps/2,L)+asr(c,b,eps/2,R);
    }
    // 自适应Simpson公式(主过程)
    double asr(double a,double b,double eps)
    {
        return asr(a,b,eps,simpson(a,b));
    }
    自适应simpson积分

    康托展开:

    X = an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!

    其中,ai为当前未出现的元素中是排在第几个(从0开始)。

    int f(vector<int> v)
    {
        int sum = 0;
        for(int i = 0;i < 8;i++)
        {
            int t = 0;
            for(int j = i+1;j < 8;j++)
            {
                if(v[i] > v[j]) t++;
            }
            sum += t*h[7-i];
        }
        return sum;
    }
    康托展开

    //f[]:可以取走的石子个数
    //sg[]:0~n的SG函数值
    //hash[]:mex{}
    int n,m,p,f[N],sg[N],hashh[N]; 
        
    void getSG(int n)
    {
        memset(sg,0,sizeof(sg));
        for(int i = 1;i <= n;i++)
        {
            memset(hashh,0,sizeof(hashh));
            for(int j = 1;f[j] <= i;j++)    hashh[sg[i-f[j]]] = 1;
            for(int j = 0;j <= n;j++)        //求mes{}中未出现的最小的非负整数
            {
                if(hashh[j] == 0)
                {
                    sg[i] = j;
                    break;
                }
            }
        }
    }
    sg函数

    1. 若划分的多个整数可以相同
    
    设dp[i][j]为将i划分为不大于j的划分数。
    
    (1) 当i<j 时,i不能划分为大于i的数,dp[i][j]=dp[i][i]。
    
    (2) 当i>j 时,可以根据划分中是否含有j分为两种情况。
    
      若划分中含有j,划分方案数为dp[i-j][j]。
    
      若划分数中不含j,相当于将i划分为不大于j-1的划分数,为dp[i][j-1]。
    
      所以当i>j时,dp[i][j]=dp[i-j][j]+dp[i][j-1]。
    
    (3) 当i=j 时,若划分中含有j只有一种情况,若划分中不含j相当于将i划分为不大于j-1的划分数。此时dp[i][j]=1+dp[i][j-1]。
    
    
    2.将n划分为k个整数的划分数
    
    dp[i][j]表示将i划分成j个正整数的划分数。
    
    (1) 当i<j时,i不能划分成j个正整数,dp[i][j]=0。
    
    (2) 当i=j时,只有一种情况,dp[i][j]=1。
    
    (3) 当i>j时, 此时根据含1和不含1,故dp[i][j]=dp[i-1][j-1]+dp[i-j][j]。
    
    
    3. 若划分的正整数必须不同
    
    设dp[i][j]为将i划分为不超过j的不同整数的划分数。
    
    (1) 当i<j时,i不能划分为大于i的数,所以dp[i][j]=dp[i][i]。
    
    (2) 当i>j时,可以根据划分中是否含有j分为两种情况。
    
      若划分中含有j,则其余的划分中最大只能是j-1,方案数为dp[i-j][j-1]。
    
      若划分中不含j,相当于将i划分为不大于j-1的划分数,为dp[i][j-1]。
    
      所以当i>j时dp[i][j]=dp[i-j][j-1]+dp[i][j-1]。
    
    (3) 当i=j时,若划分中含有j只有一种情况,若划分中不含j相当于将i划分为不大于j-1的划分数。此时dp[i][j]=1+dp[i][j-1]。
    
     
    4.将n划分为若干正奇数之和的划分数
    
    设f[i][j]为将i划分为j个奇数之和的划分数,g[i][j]为将i划分为j个偶数之和的划分数。
    
    使用截边法,将g[i][j]的j个划分都去掉1,可得g[i][j] = f[i-j][j]。
    
    f[i][j]中有包含1的划分方案和不包含1的划分方案。
    
      对于包含1的划分方案,可以将1的划分除去,转化为“将i-1划分为j-1个奇数之和的划分数”,即f[i-1][j-1]。
    
      对于不包含1的划分方案,可以使用截边法对j个划分每一个都去掉一个1,转化为“将i-j划分为j个偶数之和的划分数”,即g[i-j][j]。
    
      所以f[i][j]=f[i-1][j-1]+g[i-j][j]。
    
    f[n][0]+f[n][1]+……+f[n][n]为将n划分为若干奇数的划分数。
    整数划分分类

    Polya定理:设 G = {a1,a2,…,ag}是 N 个对象的置换群,用 M 种颜色给这 N 个对象着色,

    则不同的着色 方案数为:|G|^(-1) * {M^c(a1) + M^c(a2) + … + M^c(ag)}。其中 c(ai)为置换 ai 的循环节数,( i = 1,2,…,g )。


    设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。

    如果g是P的原根,那么g的(1...P-1)次幂mod P的结果一定互不相同。

    如果g是P的原根,就是g^(P-1) = 1 (mod P)当且仅当指数为P-1的时候成立.(这里P是素数).

    int n,a[35000],cnt = 0;
    
    LL qmod(LL a, LL b, LL c)
    {
        LL ans = 1;
        a = a%c;
        while(b)
        {
            if(b&1)    ans = ans*a%c;
            b >>= 1;
            a = a*a%c;
        }
        return ans;
    }
    
    int main()
    {
        scanf("%d",&n);
        int endd = sqrt(n-1);
        for(int i = 2;i <= endd;i++)
        {
            if((n-1)%i == 0)    a[++cnt] = i;
        }
        for(int i = 2;i <= n-1;i++)
        {
            int j;
            for(j = 1;j <= cnt;j++)
            {
                if(qmod(i,a[j],n) == 1 || qmod(i,(n-1)/a[j],n) == 1)    break;
            }
            if(j == cnt+1)
            {
                printf("%d
    ",i);
                return 0;
            }
        }
    }
    求原根

    卡特兰数 1, 2, 5, 14, 42

    h(0) = 1,h(1) = 1
    
    h(n) = h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
    
    h(n) = h(n-1)*(4*n-2)/(n+1)
    
    h(n) = C(2n,n)/(n+1) 
    
    h(n) = C(2n,n)-C(2n,n-1)
    
    1.n对括号正确匹配组成的字符串数。
    
    2.一个栈(无穷大)的进栈序列为1,23,…,n,有多少个不同的出栈序列。
    
    3.在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形,求不同划分的方案数f(n)。
    
    4.一位大城市的律师在她住所以北n个街区和以东n个街区处工作。
    
    5.长度为 2n的 Dyck words的数量。 Dyck words是由 n个 X和 n个 Y组成的字符串,并且从左往右数, Y的数量不超过 X。
    
    6.拥有 n+1 个叶子节点的二叉树的数量。例如 4个叶子节点的所有二叉树形态。
    
    7.圆桌握手问题: 圆桌周围有 2n个人,他们两两握手,但没有交叉的方案数。
    卡特兰数

    调和级数

    f(n)ln(n)+C+1/2*n    (n很大时)

    C≈0.57721566490153286060651209


  • 相关阅读:
    文件流:"fopen","fclose",“ftell”"fseek","fgets","fprintf" ,“feof”,"fwrite","fread"
    “/”和“\”和feof();
    VS快捷键说明
    vs2015安装VAssistX以后,去除中文注释会有红色下划线方法
    QT5.8+vs2015配置以及qt creater中出现中文乱码解决办法之一
    将ascll码转换成数值进行运算
    二维数组---指针数组和数组指针
    source insight 4.0.086破解
    make clean 和make distclean的区别
    长歌行
  • 原文地址:https://www.cnblogs.com/zhurb/p/7309307.html
Copyright © 2020-2023  润新知