LOG 模拟赛
第一次见尼玛这么给数据范围的……
开考有点困,迷迷糊糊看完了三道题,真的是像老吕说的那样,一道都不会……
思考T1,感觉有点感觉,但是太困了,就先码了暴力,发现打表可以50分,于是就大力打了一波表……转身T3,码出25分的O(n^2)算法,然后不会了……去了T2,码出35分的O(n^2)bfs,然后不会了……+
考试还有1h+,我又看了一遍三道题,发现并没有什么新的思路,于是决定去想T1,继续考试一开始的思路——我发现每加一位,一定是在原合法方案的基础上加的.想到这里,我就迅速码出,发现需要写尼玛高精度,然而考试还剩下不到10min……我估了一下我现在这题的分——70分,于是决定不打高精度了……
最后70+35+25=130……
后来发现我的T1做法基本就是正解了,只要再写上一个漂亮的高精度就可以A掉了……而正解呢,只不过是继续把性质推了一下然后把我的刷表法变成了填表法……
T3正解是,在我的思路的基础之上,利用题目给出的随机树的条件,把我每次都要重新处理的东西记录了下来,这样像动态点分治一样每次查询加修改就可以了……
思维笔记:I.信息共用以减少处理次数 II.利用随机
算法笔记:I.随机树(我们假设其为有根树)树高期望log(实际上都快到根号级别了) II.随机树(我们假设其为有根树)中,每个点的子树树高与其在整棵树中的深度的乘积的加和的期望是n^1.5的
T2好神啊……


 

雀巢咖啡系列模拟赛 XLI
异化多肽(T1):
看到这个东西还有那个模数就像要去ntt一发,然后开始推式子.
推啊推,推啊推,推出来一个等比数列求和的式子,很开心,感觉自己要A题了.
然后快速码出快速幂ntt+多项式求逆,调完之后,极限数据5s!!!感觉药丸,然后一波卡常,3s左右,就没再管……
最后90,T了一个点,发现一个很蠢蛋的问题——我凑,我快速幂ntt个蛋啊,mdzz,我要快速幂ntt求的那个多项式在mod x^(n+1)意义下是0啊!!!!感觉自己蠢到家了……
所以这题只不过是一个比较裸的多项式求逆,我为什么要快速幂ntt呢?应该就是我多项式这儿太菜了,当然我觉得也有考试的时候脑子不太正常的原因,还有我的极限思想应该是不太好.
推出这道题的多项式求逆还可以直接从生成函数的实际意义和递推式的角度.

#pragma GCC optimize("O3")
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const int N=100010;
const int P=1005060097;
inline int Pow(int x,int y){
  int ret=1;
  while(y){
    if(y&1)ret=(LL)ret*x%P;
    x=(LL)x*x%P,y>>=1;
  }return ret;
}
int A[N<<2],ai[N<<2],rev[N<<2],inv[N<<2],len;
int n,m;
inline void ntt(int *C,int opt){
  register int i,j,k,w;int wn,temp;
  for(i=1;i<len;++i)if(rev[i]>i)std::swap(C[i],C[rev[i]]);
  for(k=2;k<=len;k<<=1){
    wn=Pow(5,(P-1)/k);
    if(opt==-1)wn=Pow(wn,P-2);
    for(i=0;i<len;i+=k){
      w=1;
      for(j=0;j<(k>>1);++j,w=(LL)w*wn%P){
        temp=(LL)w*C[i+j+(k>>1)]%P;
        C[i+j+(k>>1)]=(C[i+j]-temp+P)%P;
        C[i+j]=(C[i+j]+temp)%P;
      }
    }
  }
}
inline void get_inv(int *a,int *b,int cd){
  if(cd==1){b[0]=Pow(a[0],P-2);return;}
  get_inv(a,b,cd>>1),len=cd<<1;
  int i,ni=Pow(len,P-2);
  for(i=1;i<len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)?(len>>1):0);
  memcpy(A,a,cd<<2),memset(A+cd,0,cd<<2);
  ntt(A,1),ntt(b,1);
  for(i=0;i<len;++i)b[i]=(2-(LL)b[i]*A[i]%P+P)%P*(LL)b[i]%P;
  ntt(b,-1);
  for(i=0;i<cd;++i)b[i]=(LL)b[i]*ni%P;
  memset(b+cd,0,cd<<2);
}
int main(){
  scanf("%d%d",&n,&m);int i,x;
  for(i=1;i<=m;++i)
    scanf("%d",&x),++ai[x];
  ai[0]=P-1,len=1;
  while(len<=n)len<<=1;
  get_inv(ai,inv,len);
  printf("%d\n",(P-inv[n])%P);
  return 0;
}
Kod

相关文章: