zoukankan      html  css  js  c++  java
  • 数学专题测试1 题解

    A. 解方程

    考虑没有任何限制的东西,

    m个元素分为n个连续的区间,直接用组合数插板法就好了。

    考虑如何去掉元素大于$a_i$的限制,

    只要给最终的元素个数减掉$a_i$就好了。

    考虑如何搞元素个数小于$a_i$的限制,

    不妨使用子集反演,要求的是恰好$0$个元素大于$a_i$。

    只要钦定其中的每个集合元素大于$a_i$,问题就转化为了容易解决的问题,乘上容斥系数就好了。

    因为模数满足$p^k$并不大,使用$exlucas$(实际上就是不断提取$p$这个质因子)就好了。

    B. 宇宙序列

    因为异或的性质$a xor b xor b=a$,题中给出的式子可以转化为异或卷积式。

    因为异或卷积具有结合律,可以直接倍增求,使用FWT优化,可以做到$O(pn2^n)$。

    通过DFT,可以将异或的卷积式转化为对位相乘。

    暴力相加并不容易优化,但是可以发现对位相乘的结果的形式是优美的。

    根据异或FWT的DFT性质(可以结合或卷积的子集和理解),可以发现不断在系数/点值两种情况下转换是没有意义的。

    只要在点值意义下不断的自乘,累加在另一个数组中就可以了。

    设$a$数组DFT之后为$A$数组,那么对于$A_i$,对应的累加结果为$B_i=sum limits_{j=0}^{p}A_i^{2^j}$。

    问题在于求出$B$,一次性IDFT回去就好了。

    利用本题中模数并不大($10007$)的性质,找一下循环节可以做到$O(mod^2)$预处理。

    然而正解是一个倍增。

    设$f_{x,k}=sum limits_{j=0}^{2^k-1}x^{2^j}$

    有$f_{x,k}=f_{x,k-1}+f_{x^{2^{2^{k-1}}},k-1}$

    询问的时候只要用类似的方法倍增统计就好了。

    用一些特殊的技巧,可以将总复杂度做到$O(mod*logp+n*2^n)$。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int mod=10007;
     4 const int inv2=5004;
     5 const int N=262150;
     6 int n,p,d,lim;
     7 int a[N],f[mod][32];
     8 inline void fwt(int opt){
     9     for(int i=1;i<lim;i<<=1)
    10         for(int j=0;j<lim;j+=i<<1)
    11             for(int k=0;k<i;++k){
    12                 int x=a[j+k],y=a[j+k+i];
    13                 a[j+k]=(x+y)%mod; a[j+k+i]=(x-y+mod)%mod;
    14                 if(opt==-1) a[j+k]=a[j+k]*inv2%mod,a[j+k+i]=a[j+k+i]*inv2%mod;
    15             }
    16 }
    17 inline int qpow(int x,int k,int mod,int r=1){
    18     for(;k;k>>=1,x=x*x%mod) if(k&1) r=r*x%mod;
    19     return r;
    20 }
    21 inline int query(int x,int k,int ans=0,int r=0){
    22     for(int i=0;i<30;++i) if(k>>i&1) ans+=f[qpow(x,qpow(2,r%5002,mod-1),mod)][i],r+=1<<i;
    23     return ans%mod;
    24 }
    25 inline int read(register int x=0,register char ch=getchar(),register int f=0){
    26     for(;!isdigit(ch);ch=getchar()) f=ch=='-';
    27     for(; isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
    28     return f?-x:x;
    29 }
    30 int main(){
    31     n=read(); p=read(); d=read(); lim=1<<n;
    32     for(int i=0;i<lim;++i) a[i]=read();
    33     for(int i=0;i<mod;++i) f[i][0]=i;
    34     for(int i=1;i<30;++i) for(int j=0;j<mod;++j) f[j][i]=(f[j][i-1]+f[qpow(j,qpow(2,(1<<i-1)%5002,mod-1),mod)][i-1])%mod;
    35     fwt(1);
    36     for(int j=0;j<lim;++j) a[j]=query(a[j],p+1);
    37     fwt(-1);
    38     printf("%d
    ",a[d]);
    39     return 0;
    40 }
    T2

    C. exp

    不会做+看不懂,就没什么好说的。

    UPD:大概看懂了新题解,并颓了std,所以AC了。

    可以发现,对于区间$[l,r]$,找出其中的一个O,设下标为$k$。

    可以划分为$[l,k]$,$[k+1,r]$两个区间,在不选择$k$的情况下,可以视为两个区间互不干涉,于是可以以此为依据进行DP。

    设$f_{l,r}$表示消完区间$[l,r-1]$,最后一个O下标为$r$,还没有消对应的期望。

    $g_{l,r}$与上述定义相同,但为概率。

    $p(l,r,k)$表示区间$[l,k-1]$已经消完,区间$[k+1,r-1]$已经消完,$k$最后一个被消为X,$r$还没有消的概率。

    对于$p(l,r,k)$,设区间$[l,k-1]$中有$lc$个O,区间$[k+1,r-1]$中有$rc$个O。

    有$p(l,r,k)=inom{lc+rc}{lc}*(frac{k-l+1}{r-l+1})^{lc}*g_{l,k}*(frac{r-k}{r-l+1})^{rc}*g_{k+1,r}*frac{k-l+1}{r-l+1}$

    为了便于理解,可以考虑一个特殊情况:$k-l+1=r-k$,有选择右侧概率和选择右侧概率相同。

    那么原式可以写为$p(l,r,k)=frac{inom{lc+rc}{lc}}{2^{lc+rc}}*g_{l,k}*g_{k+1,r}*frac{1}{2}$,这里的概率即选择左右次数恰好合法的方案除以每个不同的方案。

    对于选择左侧和右侧概率不同的情况,也可以在方案数的角度考虑。

    首先考虑使选择左右次数分别合法的方案数:

    $(k-l+1)^{lc}*(r-k)^{rc}*inom{lc+rc}{lc}$,即首先在左侧选择$lc$次,再在右侧选择$rc$次。

    然而并没有要求左右的严格顺序,所以要乘一个组合数。

    使最后一次合法,贡献为乘$(k-l+1)$。

    总的方案数是$(r-l+1)^{lc+rc+1}$,所以这个式子就推出来了。

    $g_{l,r}=sum limits_{k=l}^{r-1}p(l,r,k)$

    $f_{l,r}=frac{1}{g_{l,r}}sumlimits_{k=l}^{r-1} p(l,r,k)*(f_{l,k}+f_{k+1,r}+frac{k-l}{2})$

    因为有上式$g$数组的求和式,$f$的转移式实际上是期望的一个加权平均。

    考虑最后一次操作补上$k$位置对期望的贡献,设$n=k-l+1$。

    有$E=frac{sum limits_{i=0}^{n-1}i}{n}=frac{n-1}{2}$。

    原式中的$frac{k-i}{2}$与上述的$frac{n-1}{2}$比较类似,最后的一次只在左侧选择,即将$n=k-i+1$代入。

    当$[l,r]$区间内仅有$r$为O,有初态$f_{l,r}=0$,$g_{l,r}=1$。

    统计答案考虑断环成链,最后一次贡献的期望是$frac{n-1}{2}$,枚举最后一个变为X的O。

    $ans=sum limits_{i=1}^{n}g_{i,i+n-1}*f_{i,i+n-1}$

    因为$sum limits_{i=1}^ng_{i,i+n-1}=1$,这样不除总概率(等于1)的做法是合理的。

  • 相关阅读:
    根据数据类型选择特征 select_dtypes(include=[]/exclude=[])
    quantile()
    concat()、merge()的区别
    json.dumps()和json.loads()
    Linux-top命令详解
    性能测试总结(一)---基础理论篇
    jmeter-常见问题及解决方法
    Jmeter之Bean shell使用(五)
    Jmeter-内存溢出原因及解决方法
    JMeter- JDBC Request
  • 原文地址:https://www.cnblogs.com/skyh/p/12134383.html
Copyright © 2011-2022 走看看