专项测试(数学2)
这我今天补昨天的博客,真是可怜,昨晚\(21:40:05\)改完的题......
这一场还是很好的一场,因为我没切题...其实我还挺郁闷的
如何才能让我前两个题多测没换行痛失30分,没事一共就得了30分,加起来也就60
T1 猜拳游戏
一遇到这种最优策略的问题,我是这样的:
题意:两个人都绝顶聪明!
我:我没他俩聪明......
题意:两个人采取最优策略!
我:最优策略是啥??我不知道啊,也没人告诉我最优策略是啥啊?
题意:要赢!
我:咋我的策略是赢,然后概率不对嘞
对面摇摆兵:有的时候不输就行了
于是发现平局对答案没有影响,我们设赢的概率为\(p\),输的概率是\(r\),那么最后我们转化题意之后的赢的概率就是\(\frac{p}{p+r}\)
这个东西就要分数规划啦!!
二分\(\frac{p}{r}\)的值,用\(dp\)判断,我们\(dp\)出来\(p-r*mid\)的最大值
最后屌丝消元一下就好了,跟我念'高(diao)斯(si)消(xiao)元(yuan)'!
code
#include<bits/stdc++.h>
using namespace std;
#define ld 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 ld eps=1e-9;
const int N=1010;
int n,m1,m2,r[N],p[N],s[N];
ld ans,dp[N][N*2];
bool ck(ld mid){
fo(i,0,n-1)dp[n+1][i]=-mid;dp[n+1][n]=0;
fo(i,n+1,n*2)dp[n+1][i]=1.0;
fu(i,n,1){
fo(j,0,2*n){
ld res1=0,res2=0,res3=0;
if(j<2*n)res1+=s[i]/100.0*dp[i+1][j+1];
res1+=r[i]/100.0*dp[i+1][j];
if(j>0)res1+=p[i]/100.0*dp[i+1][j-1];
if(j<2*n)res2+=p[i]/100.0*dp[i+1][j+1];
res2+=s[i]/100.0*dp[i+1][j];
if(j>0)res2+=r[i]/100.0*dp[i+1][j-1];
if(j<2*n)res3+=r[i]/100.0*dp[i+1][j+1];
res3+=p[i]/100.0*dp[i+1][j];
if(j>0)res3+=s[i]/100.0*dp[i+1][j-1];
dp[i][j]=max(max(res1,res2),res3);
}
}
return dp[1][n]>=0;
}
ld a[N][N],x[N];
ld dsxy(int n){
for(int h=1,z=1;h<=n&&z<=n;h++,z++){
int mx=h;
fo(i,h+1,n)if(fabs(a[i][z])>fabs(a[mx][z]))mx=i;
if(mx!=h)fo(i,z,n+1)swap(a[mx][i],a[h][i]);
if(!a[h][z])continue;
fo(i,h+1,n){
ld t=a[i][z]/a[h][z];
fo(j,z,n+1)a[i][j]-=a[h][j]*t;
}
}
memset(x,0,sizeof(x));
fu(i,n,1){
ld t=a[i][n+1];
fo(j,i+1,n)t-=a[i][j]*x[j];
x[i]=t/a[i][i];
}
return x[m2];
}
signed main(){
while(true){
n=read();m1=read();m2=read();
if(n==0&&m1==0&&m2==0)break;
fo(i,1,n)r[i]=read(),p[i]=read(),s[i]=read();
ld l=1e-6,r=1e6,mid;
while(r-l>eps){
mid=(l+r)/2.0;
if(ck(mid))l=mid;
else r=mid;
}
ld q=1.0/(1.0/l+1.0);
memset(a,0,sizeof(0));
fo(i,2,m1+m2-2)a[i][i]=1,a[i][i-1]=(q-1),a[i][i+1]=-q;
a[m1+m2-1][m1+m2-1]=1;a[m1+m2-1][m1+m2]=q;
if(m1+m2-1>1){a[1][2]=-q;a[1][1]=1;a[m1+m2-1][m1+m2-2]=(q-1);}
ans=dsxy(m1+m2-1);
printf("%.5lf\n",ans);
}
return 0;
}
T2 B君的回忆
这是个傻逼找循环结题,不说了,瞎找就行了
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;
}
int T,a,b,n,k,mod,ans;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x;
x=x*x;y>>=1;
}return ret;
}
void fmod(int &x){x=x-x/mod*mod;}
struct matrix{
int x[2][2];
matrix(){memset(x,0,sizeof(x));}
bool operator < (matrix a)const{
fo(i,0,1)fo(j,0,1){
if(x[i][j]<a.x[i][j])return true;
else if(x[i][j]>a.x[i][j])return false;
}
return false;
}
bool operator == (matrix a)const{
fo(i,0,1)fo(j,0,1){
if(x[i][j]!=a.x[i][j])return false;
}
return true;
}
matrix operator * (matrix a)const{
matrix ret;
fo(i,0,1)fo(j,0,1){
if(!x[i][j])continue;
fo(k,0,1)ret.x[i][k]=(ret.x[i][k]+x[i][j]*a.x[j][k]);
}
fo(i,0,1)fo(j,0,1)fmod(ret.x[i][j]);
return ret;
}
}xs,ma;
matrix mksm(matrix x,int y){
matrix ret;
ret.x[0][0]=ret.x[1][1]=1;
while(y){
if(y&1)ret=ret*x;
x=x*x;y>>=1;
}return ret;
}
map<matrix,int> mp;
unordered_map<int,int> finm;
int bsgs(int mo){
if(finm.find(mo)!=finm.end())return finm[mo];
int sq=sqrt(max(mo,(int)2e9))+1;
mod=mo;xs.x[1][0]=mod-1;
matrix adds,addy=xs,now;
now.x[0][0]=1;now.x[1][1]=1;
if(mksm(xs,mod)==now)return finm[mo]=mod;
if(mksm(xs,mod+1)==now)return finm[mo]=mod+1;
if(mksm(xs,mod-1)==now)return finm[mo]=mod-1;
mp.clear();mp[now]=0;
fo(i,1,sq-1){now=now*xs;mp[now]=i;}
adds=now*xs;
now.x[0][0]=1;now.x[1][1]=1;
now.x[1][0]=0;now.x[0][1]=0;
fo(i,1,sq){
now=now*adds;
if(mp.find(now)!=mp.end())return finm[mo]=i*sq-mp[now];
}
return 2e9;
}
int fj[205],cnt,ci[205];
int p[1000005],cp,R=1e6;bool vis[1000005];
void init(){
fo(i,2,R){
if(!vis[i])p[++cp]=i;
for(int j=1;j<=cnt&&i*p[j]<=R;j++){
vis[i*p[j]]=true;
if(i%p[j]==0)break;
}
}
}
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int lcm(int x,int y){return x/gcd(x,y)*y;}
int bsg(int mo){
if(finm.find(mo)!=finm.end())return finm[mo];
int now=mo;cnt=0;
for(int i=1;p[i]*p[i]<=now;i++){
if(now%p[i]==0)fj[++cnt]=p[i],ci[cnt]=0;
while(now%p[i]==0)ci[cnt]++,now/=p[i];
}
if(now>1)fj[++cnt]=now,ci[cnt]=1;
int ret=bsgs(fj[1])*ksm(fj[1],ci[1]-1);
fo(i,2,cnt){
int res=bsgs(fj[i])*ksm(fj[i],ci[i]-1);
ret=lcm(ret,res);
}
return finm[mo]=ret;
}
int get(int mo,int k){
if(k==0)return mod=mo,xs.x[1][0]=mod-1,(ma*mksm(xs,n-1)).x[0][0];
int md=bsg(mo);int ret=get(md,k-1);
if(!ret)return a;
return mod=mo,xs.x[1][0]=mod-1,(ma*mksm(xs,ret-1)).x[0][0];
}
signed main(){
T=read();init();
while(T--){
a=read();b=read();n=read();k=read();mod=read();
xs.x[0][0]=3;xs.x[0][1]=1;xs.x[1][0]=-1;xs.x[1][1]=0;
ma.x[0][0]=b;ma.x[0][1]=a;ma.x[1][0]=a;
ans=get(mod,k-1);
printf("%lld\n",ans);
}
return 0;
}
T3 小H爱染色
就说一句,有时候需要钦定的时候,如果可以在混乱中,也就是不钦定得到答案,那就可以变换一下
code
#include<bits/stdc++.h>
using namespace std;
#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=998244353;
const int N=1<<22;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}return ret;
}
int n,m,a[N],b[N],ans;
int jc[N],inv[N],F[N],xjm[N];
int C(int x,int y){return 1ll*jc[x]*inv[y]%mod*inv[x-y]%mod;}
int D(int y){return 1ll*xjm[y]*inv[y]%mod;}
int f[N],h[N],g[N],af[N],len,lim;
int qmod(int x){return x>=mod?x-mod:x;}
void ntt(int *a,int lim){
fo(i,0,lim-1)if(af[i]>i)swap(a[i],a[af[i]]);
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=1ll*g[t*j]*a[i+j+d]%mod;
a[i+j+d]=qmod(a[i+j]-tmp+mod);
a[i+j]=qmod(a[i+j]+tmp);
}
}
signed main(){
n=read();m=read();
jc[0]=1;fo(i,1,3*m)jc[i]=1ll*jc[i-1]*i%mod;
inv[0]=1;inv[3*m]=ksm(jc[3*m],mod-2);
fu(i,3*m-1,1)inv[i]=1ll*inv[i+1]*(i+1)%mod;
fo(i,0,m)F[i]=1ll*read()*inv[i]%mod;
fo(i,0,m)f[i]=1ll*(i&1?mod-1:1)*inv[i]%mod;
xjm[0]=1;fo(i,1,3*m)xjm[i]=1ll*xjm[i-1]*(n-i+1)%mod;
for(lim=1,len=0;lim<=2*m;lim<<=1,len++);
fo(i,0,lim-1)af[i]=(af[i>>1]>>1)|((i&1)<<(len-1));
g[0]=1;g[1]=ksm(3,(mod-1)/lim);
fo(i,2,lim-1)g[i]=1ll*g[i-1]*g[1]%mod;
ntt(f,lim);ntt(F,lim);
fo(i,0,lim-1)f[i]=1ll*f[i]*F[i]%mod;
g[0]=1;g[1]=ksm(g[1],mod-2);
fo(i,2,lim-1)g[i]=1ll*g[i-1]*g[1]%mod;
ntt(f,lim);int iv=ksm(lim,mod-2);
fo(i,0,lim-1)f[i]=1ll*f[i]*iv%mod*jc[i]%mod;
fo(i,m+1,lim-1)f[i]=0;
fo(i,m,2*m)h[i]=1ll*C(i,m)*C(m,2*m-i)%mod;
for(lim=1,len=0;lim<=3*m;lim<<=1,len++);
fo(i,0,lim-1)af[i]=(af[i>>1]>>1)|((i&1)<<(len-1));
g[0]=1;g[1]=ksm(3,(mod-1)/lim);
fo(i,2,lim-1)g[i]=1ll*g[i-1]*g[1]%mod;
ntt(f,lim);ntt(h,lim);
fo(i,0,lim-1)f[i]=1ll*f[i]*h[i]%mod;
g[0]=1;g[1]=ksm(g[1],mod-2);
fo(i,2,lim-1)g[i]=1ll*g[i-1]*g[1]%mod;
ntt(f,lim);iv=ksm(lim,mod-2);
fo(i,0,lim-1)f[i]=1ll*f[i]*iv%mod;
fo(i,m,3*m)ans=(ans+1ll*D(i)*f[i]%mod)%mod;
printf("%d",ans);
return 0;
}
QQ:2953174821