ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

noip模拟51[好IOI]

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

标签:bas noip int 51 re xds ji IOI mod


noip模拟51 solutions

好像是和别的学校一起考得

然后我交错比赛了,变成了\(IOI\)赛制,交上去就是俩\(AC\)

所以这次的题前两个过于水了。。。。

T1 茅山道术

就是找在当前条件下的,序列不重合划分的方案数,直接\(DP\),类似前缀和优化一下

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 万猪拱塔

首先看题要看准,\(k\)是互不相同的

所以我当前矩形的数一定是一个连续的区间

直接枚举这个区间判断是否构成矩形

按着题解上说的,枚举右端点,更新所在的四个小矩形,线段树

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);
}

T4 沽

标签:bas,noip,int,51,re,xds,ji,IOI,mod
来源: https://www.cnblogs.com/hzoi-fengwu/p/15270554.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有