日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

noip模拟9 达哥随单题

發(fā)布時間:2024/8/1 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 noip模拟9 达哥随单题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

T1.隨

  看題第一眼,就瞄到最下面 孫金寧教你學(xué)數(shù)學(xué)? ?????原根?目測神題,果斷跳過。

  最后打了個快速冪,愉快的收到了達哥送來的10分。

  實際上這題暴力不難想,看到一個非常小的mod應(yīng)該就能想到復(fù)雜度與mod有關(guān),然后dp式子也挺顯然的。

  比較神的是最后的優(yōu)化,我們用?f[i][j]表示經(jīng)過i次操作,最終%mod后與原根的j次方同余的方案數(shù),然后,之前的轉(zhuǎn)移

  f[i][j*k%mod]=f[i-1][j]*sum[k](sum[k]為k在n個數(shù)中出現(xiàn)的次數(shù))?就變成了f[ i ] [ ( j + k ) % ( mod-1 ) ]=f[i-1][j]*sum[k];

  那么這有什么卵用呢,原來的轉(zhuǎn)移矩陣變成了循環(huán)矩陣,于是乎就可以mod^2乘一次。

  另外,對于這道題,原根沒有必要O(mod1/4)求,mod^2暴力就行。。。

  總復(fù)雜度O(mod^2logm).

  數(shù)據(jù)差評,沒有80分算法

?

1 #include<bits/stdc++.h> 2 #define p 1000000007 3 using namespace std; 4 int n,m,mod,a,sum[1005],yuan,ys[1005],yx[1005]; 5 long long b[1000][1000],aa[1000],c[1000],d[1000]; 6 bool v[1000]; 7 inline void cheng() 8 { 9 for(int i=1;i<mod;i++) 10 { 11 d[i]=0; 12 for(int j=1;j<mod;j++) 13 d[i]=(d[i]+aa[j]*b[j][i])%p; 14 } 15 for(int i=1;i<mod;i++) 16 aa[i]=d[i]; 17 } 18 inline void z() 19 { 20 for(int i=1;i<mod;i++) 21 { 22 c[i]=0; 23 for(int j=1;j<mod;j++) 24 c[i]=(c[i]+b[1][j]*b[j][i])%p; 25 } 26 for(int i=1;i<mod;i++) 27 b[1][i]=c[i]; 28 for(int i=2;i<mod;i++) 29 for(int j=1;j<mod;j++) 30 b[i][j]=b[i-1][(j==1)?mod-1:j-1]; 31 } 32 inline long long qpow(long long x,long long y) 33 { 34 long long ans=1; 35 while(y) 36 { 37 if(y&1)ans=ans*x%p; 38 x=x*x%p; 39 y>>=1; 40 } 41 return ans; 42 } 43 int main() 44 { 45 scanf("%d%d%d",&n,&m,&mod); 46 for(int i=1;i<mod;i++) 47 { 48 memset(v,0,sizeof(v)); 49 long long k=1; 50 bool kkk=0; 51 for(int j=1;j<mod;j++) 52 { 53 if(v[(k*i)%mod]) 54 { 55 kkk=1; 56 break; 57 } 58 k=(k*i)%mod,v[k]=true; 59 } 60 if(!kkk) 61 { 62 yuan=i; 63 break; 64 } 65 } 66 for(int i=1,j=yuan;i<mod;i++,j=j*yuan%mod) 67 ys[j]=i,yx[i]=j; 68 for(int i=1;i<=n;i++) 69 scanf("%d",&a),sum[ys[a]]++; 70 for(int i=1;i<mod;i++) 71 for(int j=1;j<mod;j++) 72 b[i][(i+j-1)%(mod-1)+1]+=sum[j]; 73 aa[mod-1]=1; 74 long long bb=qpow(n,m),aaa=0; 75 while(m) 76 { 77 if(m&1) cheng(); 78 z(); 79 m>>=1; 80 } 81 for(int i=1;i<mod;i++) 82 (aaa+=yx[i]*aa[i])%=p; 83 cout<<aaa*qpow(bb,p-2)%p; 84 return 0; 85 } View Code

?

T2.單

  這也是一道很帥的題,首先對于t=0的操作,令sum為所有節(jié)點的權(quán)值之和,我們首先進行暴力求出b[1]的值,然后對于其他節(jié)點,我們可以進行換根:

  b[x]=b[fa]-siz[x]+(sum-siz[x]);這個式子比較顯然。于是30分到手。

  對于t=1的操作,我們把上面那個式子變一下就可以得到2*siz[x]=b[fa]-b[x]+sum。也就是說,我們只要求出sum的值,就可以求出所有的a。

  考試的時候就死在了這里,發(fā)現(xiàn)不會求sum,不同與其他人的高斯消元,我采取了一種更為sha diao的做法:枚舉sum值,代進去看能不能成立。。。。。由于題中有a[i]<=100的限制,所以sum不會很大,理論上有60分,但是不知道為啥死掉了。

  實際上,有一個隱藏的條件:d[1]=∑siz[i] (2<=i<=n),然后我們將上面那個式子x=2到x=n的情況全都寫下來相加,將前面這個式子×2,再將這兩部分相減,我們就會驚喜的發(fā)現(xiàn):

  sum=(∑d[fa]-d[x]-d[1]*2)/(n-1);

  于是我們就可以愉快的ac了。

1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 int t,n,fi[1000005],ne[2000005],to[2000005],tot,a[1000005],b[1000005],sum,siz[1000005],de[1000005]; 5 bool o; 6 inline void add(int x,int y) 7 { 8 ne[++tot]=fi[x]; 9 to[tot]=y; 10 fi[x]=tot; 11 } 12 void dfs1(int x,int fa) 13 { 14 siz[x]=a[x];b[1]+=(de[x]-1)*a[x]; 15 for(int i=fi[x];i;i=ne[i]) 16 { 17 int y=to[i]; 18 if(y!=fa) 19 { 20 de[y]=de[x]+1; 21 dfs1(y,x); 22 siz[x]+=siz[y]; 23 } 24 } 25 } 26 void dfs2(int x,int fa) 27 { 28 b[x]=b[fa]-siz[x]+sum-siz[x]; 29 for(int i=fi[x];i;i=ne[i]) 30 { 31 int y=to[i]; 32 if(y!=fa) 33 { 34 dfs2(y,x); 35 } 36 } 37 } 38 void dfs3(int x,int fa) 39 { 40 siz[x]=(b[fa]-b[x]+sum)>>1;a[x]=siz[x]; 41 for(int i=fi[x];i;i=ne[i]) 42 { 43 int y=to[i]; 44 if(y!=fa) 45 { 46 dfs3(y,x); 47 a[x]-=siz[y]; 48 } 49 } 50 } 51 void gsm(int x,int fa) 52 { 53 for(int i=fi[x];i;i=ne[i]) 54 { 55 int y=to[i]; 56 if(y!=fa) 57 { 58 sum+=b[x]-b[y]; 59 gsm(y,x); 60 } 61 } 62 } 63 main() 64 { 65 scanf("%lld",&t); 66 while(t--) 67 { 68 tot=sum=0; 69 memset(fi,0,sizeof(fi)); 70 memset(b,0,sizeof(b)); 71 memset(a,0,sizeof(a)); 72 memset(siz,0,sizeof(siz)); 73 memset(de,0,sizeof(de)); 74 scanf("%lld",&n); 75 for(int i=1,x,y;i<n;i++) 76 { 77 scanf("%lld%lld",&x,&y); 78 add(x,y),add(y,x); 79 } 80 cin>>o; 81 if(o) 82 { 83 for(int i=1;i<=n;i++) 84 scanf("%lld",&b[i]); 85 gsm(1,0); 86 sum=(b[1]*2-sum)/(n-1); 87 siz[1]=sum; 88 for(int i=fi[1];i;i=ne[i]) 89 { 90 dfs3(to[i],1); 91 siz[1]-=siz[to[i]]; 92 } 93 a[1]=siz[1]; 94 for(int i=1;i<=n;i++) 95 printf("%lld ",a[i]); 96 puts(""); 97 } 98 else 99 { 100 for(int i=1;i<=n;i++) 101 scanf("%lld",&a[i]),sum+=a[i]; 102 de[1]=1; 103 dfs1(1,0); 104 for(int i=fi[1];i;i=ne[i]) 105 { 106 int y=to[i]; 107 dfs2(y,1); 108 } 109 for(int i=1;i<=n;i++) 110 printf("%lld ",b[i]); 111 puts(""); 112 } 113 } 114 return 0; 115 } View Code

T3.題

  送分題,但我沒有全部接到。。

  對于opt=0,ans=C(n,n/2)^2;

  對于opt=1,ans=catalan(n);

  對于opt=2,dp即可

  對于opt=3,枚舉一個方向走的步數(shù),ans=∑catalan(i)*catalan((n-i-i)/2)*C(n,i+i);

  另外,求大神解釋我曾經(jīng)的visit題解(那兩個組合數(shù)怎么解釋啊)

1 #include<bits/stdc++.h> 2 #define mod 1000000007 3 using namespace std; 4 int n,k; 5 long long js[200005],ni[200005],f[2][2005][2005]; 6 inline long long qpow(long long x,long long y) 7 { 8 long long ans=1; 9 while(y) 10 { 11 if(y&1)ans=ans*x%mod; 12 x=x*x%mod; 13 y>>=1; 14 } 15 return ans; 16 } 17 inline long long c(long long x,long long y) 18 { 19 return js[x]*ni[x-y]%mod*ni[y]%mod; 20 } 21 int main() 22 { 23 scanf("%d%d",&n,&k); 24 js[0]=ni[0]=1; 25 for(int i=1;i<=n+n;i++) 26 js[i]=js[i-1]*i%mod,ni[i]=qpow(js[i],mod-2); 27 if(k==0) 28 { 29 printf("%lld\n",c(n,n/2)*c(n,n/2)%mod); 30 return 0; 31 } 32 if(k==1) 33 { 34 printf("%lld\n",c(n,n/2)*qpow(n/2+1,mod-2)%mod); 35 return 0; 36 } 37 if(k==2) 38 { 39 f[0][1001][1001]=1; 40 for(int i=1;i<=n;i++) 41 { 42 f[i&1][1001][1001]=(f[(i-1)&1][1001][1000]+f[(i-1)&1][1000][1001]+f[(i-1)&1][1002][1001]+f[(i-1)&1][1001][1002])%mod; 43 for(int j=1001-n;j<=1001+n;j++) 44 if(j!=1001) 45 f[i&1][1001][j]=(f[(i-1)&1][1001][j-1]+f[(i-1)&1][1001][j+1])%mod; 46 for(int j=1001-n;j<=1001+n;j++) 47 if(j!=1001) 48 f[i&1][j][1001]=(f[(i-1)&1][j-1][1001]+f[(i-1)&1][j+1][1001])%mod; 49 } 50 cout<<f[n&1][1001][1001]<<endl; 51 return 0; 52 } 53 if(k==3) 54 { 55 long long ans=0; 56 for(int i=0;i<=n/2;i++) 57 ans=(ans+c(n,i+i)*c(i+i,i)%mod*qpow(i+1,mod-2)%mod*c(n-i-i,(n-i-i)/2)%mod*qpow((n-i-i)/2+1,mod-2))%mod; 58 cout<<ans; 59 } 60 return 0; 61 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/hzoi-cbx/p/11256136.html

總結(jié)

以上是生活随笔為你收集整理的noip模拟9 达哥随单题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。