专项测试(数学3)
今天非常生气,本来要爆摇摆兵50分的结果只爆了20分......
T1 解方程
这就是一个\(exlucas\)的板子
然而当年这个板子是我硬拍过去的...
code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int N=1<<17;
int T,mod,n,n1,n2,m,a[N];
int ans;
int ksm(int x,int y,int mod){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
int p[N],pk[N],cnt;
void init_p(){
int now=mod;
for(int i=2;i*i<=now;i++){
if(now%i==0)p[++cnt]=i,pk[cnt]=1;
while(now%i==0)pk[cnt]*=i,now/=i;
}
if(now>1)p[++cnt]=now,pk[cnt]=now;
}
int exgcd(int a,int b,int &x,int &y){
if(!b)return x=1,y=0,a;
int g=exgcd(b,a%b,x,y),t=x;
x=y;y=t-a/b*y;return g;
}
int inv(int a,int b){
if(!a)return 0;
int x,y;exgcd(a,b,x,y);
return (x%b+b)%b;
}
int mul(int n,int p,int pk){
if(!n)return 1;int ret=1;
if(n/pk){
fo(i,2,pk)if(i%p)ret=ret*i%pk;
ret=ksm(ret,n/pk,pk);
}
fo(i,2,n%pk)if(i%p)ret=ret*i%pk;
return ret*mul(n/p,p,pk)%pk;
}
int exlucas(int x,int y,int p,int pk){;
int a=mul(x,p,pk),b=mul(y,p,pk),c=mul(x-y,p,pk);
int buc=0,ret=1,now;
now=x;while(now)buc+=now/p,now/=p;
now=y;while(now)buc-=now/p,now/=p;
now=x-y;while(now)buc-=now/p,now/=p;
ret=ret*a%pk*inv(b,pk)%pk*inv(c,pk)%pk*ksm(p,buc,pk)%pk;
return ret*mod/pk%mod*inv(mod/pk,pk)%mod;
}
int C(int x,int y){
if(x<y)return 0;
int ret=0;
fo(i,1,cnt)ret=(ret+exlucas(x,y,p[i],pk[i]))%mod;
return ret;
}
signed main(){
T=read();mod=read();init_p();
while(T--){
n=read();n1=read();n2=read();m=read()-n;
fo(i,1,n1+n2)a[i]=read();
fo(i,n1+1,n1+n2)m-=a[i]-1;
if(!n||m<0){printf("0\n");continue;}
ans=0;
fo(s,0,(1<<n1)-1){
int now=m,sum=0,tmp;
fo(i,1,n1)if((s>>i-1)&1)now-=a[i],sum++;
if(now<0)tmp=0;
else tmp=C(n+now-1,n-1);
if(sum&1)ans=(ans-tmp+mod)%mod;
else ans=(ans+tmp)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
T2 宇宙序列
找循环节......
也可以倍增......
看\(skyh\)的题解吧,写的可明白了
指数上倍增,很妙
code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int mod=10007;
const int N=1<<20;
int ksm(int x,int y,int mo){
int ret=1;
while(y){
if(y&1)ret=ret*x%mo;
x=x*x%mo;y>>=1;
}return ret;
}
int n,p,q,ans,an[N];
int a[N],b[N],f[mod+10][55],lim,len;
void xort(int *a,int lim,int bl){
for(int t=lim>>1,d=1;d<lim;d<<=1,t>>=1)
for(int i=0;i<lim;i+=(d<<1))
fo(j,0,d-1){
int tmp=a[i+j+d];
a[i+j+d]=(a[i+j]-tmp+mod)*bl%mod;
a[i+j]=(a[i+j]+tmp)*bl%mod;
}
}
signed main(){
// cout<<ksm(2,5003,mod-1)<<endl;
n=read();p=read();q=read();
fo(i,0,(1<<n)-1)a[i]=read();
for(lim=1,len=0;lim<(1<<n+1);lim<<=1,len++);
xort(a,lim,1);p++;
fo(i,0,mod-1)f[i][0]=i;
fo(i,1,30){
if((1ll<<i)>p)break;
fo(x,0,mod-1)f[x][i]=(f[x][i-1]+f[ksm(x,ksm(2,1ll<<i-1,mod-1),mod)][i-1])%mod;
}
fo(i,0,lim-1){
int tmp=a[i];
fu(j,30,0){
if((p>>j)&1){
an[i]=(an[i]+f[tmp][j])%mod;
tmp=ksm(tmp,ksm(2,(1ll<<j),mod-1),mod);
}
}
}
xort(an,lim,ksm(2,mod-2,mod));
ans=an[q];
printf("%lld",ans);
return 0;
}
T3 exp
概率期望\(DP\)永远是我不可企及的东西......
转移转移定义定义....
code
#include<bits/stdc++.h>
using namespace std;
// #define double long double
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*t;
}
const int N=205;
int T,n,u,s[N*2];char ch[N*2];
double ans,f[N*2][N*2],g[N*2][N*2],p[N][N][N];
double ksm(double x,int y){
double ret=1;
while(y){
if(y&1)ret=ret*x;
x=x*x;y>>=1;
}return ret;
}
double c[N][N];
double P(int l,int r,int k){
int lc=s[k-1]-s[l-1],rc=s[r-1]-s[k];
double lf=1.0*(k-l+1)/(r-l+1),rf=1.0*(r-k)/(r-l+1);
return c[lc+rc][lc]*ksm(lf,lc)*g[l][k]*ksm(rf,rc)*g[k+1][r]*lf;
}
signed main(){
T=read();
fo(i,0,200){
c[i][0]=c[i][i]=1;
fo(j,1,i-1)c[i][j]=c[i-1][j-1]+c[i-1][j];
}
while(T--){
scanf("%s",ch+1);n=strlen(ch+1);
ans=0;fo(i,1,n)if(ch[i]=='.')s[i+n]=s[i]=1;else s[i+n]=s[i]=0;
fo(i,1,n*2)s[i]+=s[i-1];
fo(i,1,n*2){
fo(j,i,i+n-1){
if(s[j]-s[i-1]==1&&s[j]-s[j-1]==1)g[i][j]=1,f[i][j]=0;
else g[i][j]=0,f[i][j]=0;
}
}
fo(len,1,n){
fo(l,1,2*n-len+1){
int r=l+len-1;if(s[r]-s[r-1]==0)continue;
if(g[l][r])continue;
fo(k,l,r-1){
if(s[k]-s[k-1]==0)continue;
double p=P(l,r,k);
g[l][r]+=p;
f[l][r]+=p*(f[l][k]+f[k+1][r]+(k-l)/2.0);
}
if(g[l][r]==0)continue;
f[l][r]/=g[l][r];
}
}
fo(i,n,2*n-1)if(s[i]-s[i-1]==1)ans+=g[i-n+1][i]*(f[i-n+1][i]+(n-1)/2.0);
printf("%.11lf\n",ans);
}
return 0;
}
QQ:2953174821