# noip模拟51[好IOI]

2021-09-15 07:35:12  阅读：20  来源： 互联网

# noip模拟51 solutions

## T1 茅山道术

AC_code ``` #include<bits/stdc++.h> using namespace std; #define re register int const int N=1e6+5; const int mod=1e9+7; int n,c[N]; vector<int> vec[N]; int dp[N],sum[N],pos[N]; signed main(){ freopen("magic.in","r",stdin); freopen("magic.out","w",stdout); scanf("%d",&n); for(re i=1;i<=n;i++)scanf("%d",&c[i]); n=unique(c+1,c+n+1)-c-1; for(re i=1;i<=n;i++)vec[c[i]].push_back(i),pos[i]=vec[c[i]].size()-1; dp[0]=0; for(re i=1;i<=n;i++){ dp[i]=dp[i-1]; if(pos[i])dp[i]=(dp[i]+sum[vec[c[i]][pos[i]-1]-1]+pos[i])%mod; if(pos[i])sum[i-1]=(dp[i-1]+sum[vec[c[i]][pos[i]-1]-1])%mod; else sum[i-1]=dp[i-1]; //cout<<dp[i]<<" "<<sum[i-1]<<" "<<sum[vec[c[i]][pos[i]-1]-1]<<" "<<pos[i]<<endl; } //cout<<endl; printf("%d",dp[n]+1); } ```

## T2 泰拳警告

AC_code ``` #include<bits/stdc++.h> using namespace std; #define int long long #define re register int const int N=3e6+5; const int mod=998244353; int n,p,pf[N],pg[N],jc[N],inv[N],ans,n2,m2[N]; int ksm(int x,int y){ int ret=1; while(y){ if(y&1)ret=ret*x%mod; x=x*x%mod; y>>=1; } return ret; } int C(int x,int y){ return jc[x]*inv[y]%mod*inv[x-y]%mod; } signed main(){ freopen("fight.in","r",stdin); freopen("fight.out","w",stdout); scanf("%lld%lld",&n,&p); pf[0]=pg[0]=1;n2=ksm(2,mod-2); pf[1]=ksm(p+2,mod-2);pg[1]=p*ksm(p+2,mod-2)%mod; jc[0]=jc[1]=1;m2[0]=1;m2[1]=2; for(re i=2;i<=n;i++){ pf[i]=pf[i-1]*pf[1]%mod; pg[i]=pg[i-1]*pg[1]%mod; jc[i]=jc[i-1]*i%mod; m2[i]=m2[i-1]*2%mod; } inv[0]=1;inv[n]=ksm(jc[n],mod-2); for(re i=n-1;i>=1;i--)inv[i]=inv[i+1]*(i+1)%mod; //cout<<ksm(9,mod-2)<<" "<<ksm(3,mod-2)<<endl; for(re i=0;i<=n;i++){ int tmp; if((n-i)&1)tmp=m2[n-i]*n2%mod*C(n,i)%mod; else tmp=(m2[n-i]*n2%mod+mod-C(n-i,n-i>>1)*n2%mod)%mod*C(n,i)%mod; ans=(ans+pg[i]*pf[n-i]%mod*(i+1)%mod*tmp%mod)%mod; //cout<<pf[i]<<" "<<pg[n-i]<<" "<<ans<<endl; } printf("%lld",ans); } ```

## T3 万猪拱塔

AC_code ``` #include<bits/stdc++.h> using namespace std; #define int long long #define re register int const int N=2e5+5; const int mod=998244353; int n,m,ans,rp; vector<int> jz[N],id[N]; struct position{ int i,j; position(){} position(int x,int y){i=x;j=y;} }ti[N]; struct XDS{ #define ls x<<1 #define rs x<<1|1 int sum[N*4],csm[N*4],res[N*4],tag[N*4]; int re_csm,re_res; void pushup(int x){ sum[x]=min(sum[ls],sum[rs]);csm[x]=0;res[x]=0; if(sum[x]==sum[ls])csm[x]+=csm[ls],res[x]+=res[ls]; if(sum[x]==sum[rs])csm[x]+=csm[rs],res[x]+=res[rs]; } void pushdown(int x){ if(!tag[x])return ; tag[ls]+=tag[x]; tag[rs]+=tag[x]; sum[ls]+=tag[x];sum[rs]+=tag[x]; tag[x]=0; } void build(int x,int l,int r){ if(l==r){ csm[x]=1;sum[x]=0;res[x]=l; return ; } int mid=l+r>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(x); return ; } void ins(int x,int l,int r,int ql,int qr,int v){ if(ql>qr)return ; if(ql<=l&&r<=qr){ sum[x]+=v;tag[x]+=v; return ; } pushdown(x); int mid=l+r>>1; if(ql<=mid)ins(ls,l,mid,ql,qr,v); if(qr>mid)ins(rs,mid+1,r,ql,qr,v); pushup(x);return ; } void query(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ if(sum[x]==4)re_csm+=csm[x],re_res+=res[x]; return ; } pushdown(x); int mid=l+r>>1; if(ql<=mid)query(ls,l,mid,ql,qr); if(qr>mid)query(rs,mid+1,r,ql,qr); pushup(x); } #undef ls #undef rs }xds; int ji[5],cnt; signed main(){ freopen("pig.in","r",stdin); freopen("pig.out","w",stdout); scanf("%lld%lld",&n,&m); jz[0].resize(m+5);jz[n+1].resize(m+5); for(re i=1;i<=n;i++){ jz[i].resize(m+5); id[i].resize(m+5); for(re j=1;j<=m;j++){ scanf("%lld",&jz[i][j]); ti[jz[i][j]]=position(i,j); } } //cout<<"Sb"<<endl; xds.build(1,1,n*m); for(re i=1;i<=n*m;i++){ int x=ti[i].i,y=ti[i].j; cnt=0; if(jz[x-1][y-1]<i)ji[++cnt]=jz[x-1][y-1]; if(jz[x][y-1]<i)ji[++cnt]=jz[x][y-1]; if(jz[x-1][y]<i)ji[++cnt]=jz[x-1][y]; sort(ji+1,ji+cnt+1); xds.ins(1,1,n*m,ji[cnt]+1,i,1); for(re j=cnt,bas=-1;j>=1;j--)xds.ins(1,1,n*m,ji[j-1]+1,ji[j],bas),bas=-bas; cnt=0; if(jz[x-1][y+1]<i)ji[++cnt]=jz[x-1][y+1]; if(jz[x][y+1]<i)ji[++cnt]=jz[x][y+1]; if(jz[x-1][y]<i)ji[++cnt]=jz[x-1][y]; sort(ji+1,ji+cnt+1); xds.ins(1,1,n*m,ji[cnt]+1,i,1); for(re j=cnt,bas=-1;j>=1;j--)xds.ins(1,1,n*m,ji[j-1]+1,ji[j],bas),bas=-bas; cnt=0; if(jz[x+1][y-1]<i)ji[++cnt]=jz[x+1][y-1]; if(jz[x][y-1]<i)ji[++cnt]=jz[x][y-1]; if(jz[x+1][y]<i)ji[++cnt]=jz[x+1][y]; sort(ji+1,ji+cnt+1); xds.ins(1,1,n*m,ji[cnt]+1,i,1); for(re j=cnt,bas=-1;j>=1;j--)xds.ins(1,1,n*m,ji[j-1]+1,ji[j],bas),bas=-bas; cnt=0; if(jz[x+1][y+1]<i)ji[++cnt]=jz[x+1][y+1]; if(jz[x][y+1]<i)ji[++cnt]=jz[x][y+1]; if(jz[x+1][y]<i)ji[++cnt]=jz[x+1][y]; sort(ji+1,ji+cnt+1); xds.ins(1,1,n*m,ji[cnt]+1,i,1); for(re j=cnt,bas=-1;j>=1;j--)xds.ins(1,1,n*m,ji[j-1]+1,ji[j],bas),bas=-bas; xds.re_csm=xds.re_res=0; xds.query(1,1,n*m,1,i); //cout<<xds.re_res<<" "<<xds.re_csm<<endl; (ans+=1ll*i*xds.re_csm-xds.re_res+xds.re_csm)%=mod; } printf("%lld",ans); } ```