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 }
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,我们可以把它理解成ai+bj。交换某一行或某一列时,相当于交换a或b中的两个元素。
观察子矩阵中的每一个元素对于一个询问的贡献,可以发现每个格子的系数相当于从这个格子出发走k+1步到达右下角(即(x2,y2))的方案数,每次可以走到两维坐标都大于等于它的一个格子(包括自己)。由此可知两维系数是独立的,对于一个格子(i,j)其系数可以写成ci∗dj的形式,因为格子的两维坐标增大是互不影响的。而ci,di就是在一维的坐标中,每次往右走若干步,走k+1次走到某一个端点的方案数。用插板法可得其为\binom{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=\binom{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}^d\binom{d}{e}(x_2+k)^e(-i)^{d-e}
如果把x_2,k看成参数,这是一个关于i的k次多项式。
我们只要对于0~10维护\sum a_i\times i^k就好了(当然,有些细节不同,仍需推式子)。对于另一维同理。修改就是交换a_x,a_y。
其实我们不需要推式子,我们只要知道系数是关于i的k次多项式,你可以暴力拆解所有的因式,就可以得到这些系数。
c_i=\binom{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:有如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 | 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的返回值最大为多少?
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步