zoukankan      html  css  js  c++  java
  • [家里训练20_02_12]ABC

    A:CF1119H加强版,k<=10。

    不太想解释。

      1 #define mod 998244353
      2 #define G2 499122177
      3 #include<bits/stdc++.h>
      4 using namespace std;
      5 typedef long long int ll;
      6 int n,m,k,a[55],p[1000005][11],mask;
      7 ll f[1<<21],**g,val[1<<21];
      8 inline ll qpow(ll x,ll y)
      9 {
     10     ll ans=1,base=x;
     11     while(y)
     12     {
     13         if(y&1)
     14             ans=ans*base%mod;
     15         base=base*base%mod;
     16         y>>=1;
     17     }
     18     return ans;
     19 }
     20 inline void FWT(ll*A,int limit)
     21 {
     22     for(int len=2;len<=limit;len<<=1)
     23         for(int i=0;i<limit/len;++i)
     24             for(int j=0;j<len/2;++j)
     25             {
     26                 ll x=A[i*len+j],y=A[i*len+j+len/2];
     27                 A[i*len+j]=(x+y)%mod;
     28                 A[i*len+j+len/2]=(x-y+mod)%mod;
     29             }
     30 }
     31 inline void IFWT(ll*A,int limit)
     32 {
     33     for(int len=2;len<=limit;len<<=1)
     34         for(int i=0;i<limit/len;++i)
     35             for(int j=0;j<len/2;++j)
     36             {
     37                 ll x=A[i*len+j],y=A[i*len+j+len/2];
     38                 A[i*len+j]=(x+y)%mod*G2%mod;
     39                 A[i*len+j+len/2]=(x-y+mod)%mod*G2%mod;
     40             }
     41 }
     42 int main()
     43 {
     44     ios::sync_with_stdio(false);
     45     cin>>n>>m;
     46     k=3;
     47     for(int i=0;i<k;++i)
     48         cin>>a[i];
     49     for(int i=1;i<=n;++i)
     50     {
     51         for(int j=0;j<k;++j)
     52             cin>>p[i][j];
     53         mask^=p[i][0];
     54         for(int j=1;j<k;++j)
     55             p[i][j]^=p[i][0];
     56     }
     57     g=new ll*[1<<m];
     58     for(int i=0;i<(1<<m);++i)
     59     {
     60         g[i]=new ll[1<<(k-1)];
     61         for(int j=0;j<(1<<(k-1));++j)
     62             g[i][j]=0;
     63         g[i][0]=n;
     64     }
     65     for(int i=0;i<k;++i)
     66         val[0]=(val[0]+a[i])%mod;
     67     for(int S=1;S<(1<<(k-1));++S)
     68     {
     69         for(int i=0;i<(1<<m);++i)
     70             f[i]=0;
     71         val[S]=a[0];
     72         for(int j=0;j<k-1;++j)
     73             if(S&(1<<j))
     74                 val[S]=(val[S]-a[j+1]+mod)%mod;
     75             else
     76                 val[S]=(val[S]+a[j+1])%mod;
     77         for(int i=1;i<=n;++i)
     78         {
     79             int s=0;
     80             for(int j=0;j<k-1;++j)
     81                 if(S&(1<<j))
     82                     s^=p[i][j+1];
     83             ++f[s];
     84         }
     85         FWT(f,1<<m);
     86         for(int i=0;i<(1<<m);++i)
     87             g[i][S]=f[i];
     88     }
     89     ll G=qpow(1<<(k-1),mod-2);
     90     for(int i=0;i<(1<<m);++i)
     91     {
     92         IFWT(g[i],1<<(k-1));
     93         ll ans=1;
     94         for(int S=0;S<(1<<(k-1));++S)
     95             ans=ans*qpow(val[S],g[i][S])%mod;
     96         f[i]=ans;
     97     }
     98     IFWT(f,1<<m);
     99     for(int i=0;i<(1<<m);++i)
    100         cout<<f[i^mask]<<" ";
    101     cout<<endl;
    102     return 0;
    103 }
    View Code

    B:给一个n*m的矩阵,一行一行从左到右编号依次加一直到n*m。有如下操作:

    1.交换x、y行。

    2.交换x、y列。

    3.询问某一个子矩阵的k次前缀和的和。

    n,m,q<=100000,k<=10。

    我们不可能直接维护整个矩阵,所以一定是把矩阵拆成两维分别维护。

    ​ 原来的第i行j列的值是$(i-1)*m+j$,我们可以把它理解成$a_i+b_j$。交换某一行或某一列时,相当于交换$a$或$b$中的两个元素。

    ​ 观察子矩阵中的每一个元素对于一个询问的贡献,可以发现每个格子的系数相当于从这个格子出发走$k+1$步到达右下角(即$(x_2,y_2)$)的方案数,每次可以走到两维坐标都大于等于它的一个格子(包括自己)。由此可知两维系数是独立的,对于一个格子$(i,j)$其系数可以写成$c_i*d_j$的形式,因为格子的两维坐标增大是互不影响的。而$c_i,d_i$就是在一维的坐标中,每次往右走若干步,走$k+1$次走到某一个端点的方案数。用插板法可得其为$inom{x+k}{k}$,其中$x$是到这个端点的距离。

    ​ 最终的答案是
    $$
    sum_{i=x1}^{x2}sum_{j=y1}^{y2}c_id_j(a_i+b_j)
    $$

    $$
    =(sum_{i=x1}^{x2}c_ia_i)(sum_{j=y1}^{y2}d_j)+(sum_{i=x1}^{x2}c_i)(sum_{j=y1}^{y2}d_jb_j)
    $$
    暴力计算这个式子,一个询问就可以$O(n+m)$求出答案。

    易得$c_i=inom{k+x_2-i}{k}=frac{(k+x_2-i)!}{k!(x2-i)!}=frac{1}{k!}(k+x_2-i)^{underline{k}}$

    我们知道
    $$
    x^{underline{n}}=sum_{i=0}^n(-1)^{n-i}s(n,i)x^i
    $$
    其中$s(n,i)$是第一类斯特林数

    将这个下降幂套进去
    $$
    (k+x_2-i)^{underline{k}}=sum_{d=0}^k(-1)^{k-d}s(k,d)(k+x_2-i)^d
    $$

    $$
    =sum_{d=0}^k(-1)^{k-d}s(k,d)sum_{e=0}^dinom{d}{e}(x_2+k)^e(-i)^{d-e}
    $$

    如果把$x_2,k$看成参数,这是一个关于$i$的$k$次多项式。

    我们只要对于0~10维护$sum a_i imes i^k$就好了(当然,有些细节不同,仍需推式子)。对于另一维同理。修改就是交换$a_x,a_y$。

    其实我们不需要推式子,我们只要知道系数是关于$i$的$k$次多项式,你可以暴力拆解所有的因式,就可以得到这些系数。

    $c_i=inom{k+x_2-i}{k}=frac{(k+x_2-i)!}{k!(x2-i)!}=frac{1}{k!}(k+x_2-i)^{underline{k}}$

    展开这个下降幂,可得

    $(k+x_2-i)^{underline{k}}=(k+x_2-i)(k+x_2-i-1)(k+x_2-i-2)...$

    将其看成关于$i$和$x_2$的二元多项式,对于每个k预处理一下这些多项式每一项的系数,询问时把$x_2$代进去。

    ​ 一次修改复杂度是$O(klogn)$的,询问是$O(k^2+klogn)$的


    C:有如下代码:

    void add_fish(long long &cnt, long long x, long long len) {
    	long long y = x % len;
    	while(h[y] != -1 && h[y] != x)
    		y = (y + 1) % len, cnt ++;
    	h[y] = x;
    }
    long long solve(long long len) {
    	for(int i = 0; i < len; i ++) h[i] = -1;
    	long long cnt = 0;
    	for(int i = 1; i <= n; i ++) add_fish(cnt, a[i], len);
    	return cnt;
    }
    

    现在给出数组a,问在long long范围内,solve的返回值最大为多少?

  • 相关阅读:
    Ubuntu 16 安装redis客户端
    crontab 参数详解
    PHP模拟登录发送闪存
    Nginx配置端口访问的网站
    Linux 增加对外开放的端口
    Linux 实用指令之查看端口开启情况
    无敌的极路由
    不同的域名可以指向同一个项目
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error
    Redis 创建多个端口
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/12300758.html
Copyright © 2011-2022 走看看