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)的做法是合理的。

  • 相关阅读:
    CodeForces 219D Choosing Capital for Treeland (树形DP)
    POJ 3162 Walking Race (树的直径,单调队列)
    POJ 2152 Fire (树形DP,经典)
    POJ 1741 Tree (树的分治,树的重心)
    POJ 1655 Balancing Act (树的重心,常规)
    HDU 2196 Computer (树形DP)
    HDU 1520 Anniversary party (树形DP,入门)
    寒门子弟
    JQuery选择器(转)
    (四)Web应用开发---系统架构图
  • 原文地址:https://www.cnblogs.com/skyh/p/12134383.html
Copyright © 2011-2022 走看看