首页 > 其他分享 >【考后总结】7 月多校国赛模拟赛 3

【考后总结】7 月多校国赛模拟赛 3

时间:2023-07-14 18:14:59浏览次数:41  
标签:校国赛 考后 int res maxn ans Data 模拟 mod

7.14 冲刺国赛模拟 36

T1 染色题

关键性质是奇数偶数位上可以放置的只有两种,若 \(i\) 和 \(i-2\) 选的颜色不同,那么在 \(i\) 位置放一个球,\([l,r]\) 的限制等价于 \([l+2,r]\) 中奇数位和偶数位不同时有球。

设 \(f_i\) 为 \(i\) 放置一个球的合法方案数,这样直接枚举上一个球所在位置,注意到奇偶性相同的没有限制,不同的只能转移一个前缀,前缀和优化 DP。

点击查看代码
int n,m;
pii p[maxn];
int cnt=0;
int lpos[maxn];
struct SegmentTree{
#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
    int tag[maxn<<2];
    inline void push_down(int rt){
        if(tag[rt]){
            tag[rt<<1]=tag[rt],tag[rt<<1|1]=tag[rt];
            tag[rt]=0;
        }
    }
    void update(int rt,int l,int r,int pl,int pr,int k){
        if(pl<=l&&r<=pr) return tag[rt]=k,void();
        push_down(rt);
        if(pl<=mid) update(lson,pl,pr,k);
        if(pr>mid) update(rson,pl,pr,k);
    }
    void dfs(int rt,int l,int r){
        if(l==r) return lpos[l]=tag[rt]?tag[rt]:l,void();
        push_down(rt);
        dfs(lson),dfs(rson);
    }
#undef mid
#undef lson
#undef rson
}S;
int f[maxn];
int sum[maxn][2];

int main(){
    freopen("colour.in","r",stdin);
    freopen("colour.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=m;++i){
        int l=read()+2,r=read();
        if(l<r) p[++cnt]=make_pair(l,r);
    }
    sort(p+1,p+1+cnt,[&](pii A,pii B){
        return A.fir>B.fir;
    });
    for(int i=1;i<=cnt;++i){
        S.update(1,1,n,p[i].fir,p[i].sec,p[i].fir);
    }
    S.dfs(1,1,n);
    f[1]=4,sum[1][1]=4;
    for(int i=2;i<=n;++i){
        f[i]=(sum[i-2][i&1]+sum[lpos[i]-1][i&1^1])%mod;
        sum[i][i&1^1]=sum[i-1][i&1^1],sum[i][i&1]=(sum[i-1][i&1]+f[i])%mod;
    }
    printf("%d\n",(sum[n][0]+sum[n][1])%mod);
    return 0;
}

T2 石头剪刀布

朴素规则可以倍增处理某个类型胜出的概率,在此基础上研究。

\(l=r\) 的特殊性质也可以倍增处理,具体是合并时讨论 \(u\) 出现在哪一侧。

\(L=l,R=r\) 的特殊性质注意到这个合并是满足分配律的,也就是可以批量处理某个区间全部作为 \(u\) 和某个区间全部不作为 \(u\) 合并。

正解就呼之欲出了,类似线段树去求解,如果 \([l,r]\) 与一个子区间有交,那么递归求 \(u\) 在这个子区间的情况并与 \(u\) 不在另一子区间的情况合并。

点击查看代码
inline int q_pow(int A,int B,int P){
    int res=1;
    while(B){
        if(B&1) res=1ll*res*A%P;
        A=1ll*A*A%P;
        B>>=1;
    }
    return res;
}

int n,m;
char s[maxn];
struct Data{
    ll R,P,S;
    Data()=default;
    Data(ll R_,ll P_,ll S_):R(R_),P(P_),S(S_){}
    Data operator+(const Data &rhs)const{
        Data res;
        res.R=(R+rhs.R)%mod,res.P=(P+rhs.P)%mod,res.S=(S+rhs.S)%mod;
        return res;
    }
};
inline Data merge(Data A,Data B){
    Data res;
    res.R=(A.R*B.R%mod+(A.R*B.P%mod+A.P*B.R%mod)%mod*inv3%mod+(A.R*B.S%mod+A.S*B.R%mod)%mod*inv3*2%mod)%mod;
    res.P=(A.P*B.P%mod+(A.R*B.P%mod+A.P*B.R%mod)%mod*inv3*2%mod+(A.P*B.S%mod+A.S*B.P%mod)%mod*inv3%mod)%mod;
    res.S=(A.S*B.S%mod+(A.R*B.S%mod+A.S*B.R%mod)%mod*inv3%mod+(A.P*B.S%mod+A.S*B.P%mod)%mod*inv3*2%mod)%mod;
    return res;
}
Data f[maxn][19],g[maxn][19];
Data solve(int l,int r,int pl,int pr,int k){
    if(pl<=l&&r<=pr) return g[l][k];
    Data res=Data(0,0,0);
    if(pl<=l+(1<<k-1)-2) res=res+merge(solve(l,l+(1<<k-1)-2,pl,pr,k-1),f[r-(1<<k-1)+1][k-1]);    
    if(pr>=r-(1<<k-1)+2) res=res+merge(f[l][k-1],solve(r-(1<<k-1)+2,r,pl,pr,k-1)); 
    return res;
}

int main(){
    freopen("rps.in","r",stdin);
    freopen("rps.out","w",stdout);
    n=read(),m=read();
    scanf("%s",s+1);
    for(int i=1;i<=n;++i){
        if(s[i]=='R') f[i][0]=g[i][1]=Data(1,0,0);
        else if(s[i]=='P') f[i][0]=g[i][1]=Data(0,1,0);
        else f[i][0]=g[i][1]=Data(0,0,1);
    }
    for(int k=1;k<=18;++k){
        for(int i=1;i+(1<<k)-1<=n;++i){
            f[i][k]=merge(f[i][k-1],f[i+(1<<k-1)][k-1]);
        }
    }
    for(int k=2;k<=18;++k){
        for(int i=1;i+(1<<k)-2<=n;++i){
            g[i][k]=merge(g[i][k-1],f[i+(1<<k-1)-1][k-1])+merge(f[i][k-1],g[i+(1<<k-1)][k-1]);
        }
    }
    while(m--){
        int L=read(),R=read(),l=read(),r=read();
        Data ans=solve(L,R,l,r,__lg(R-L+2));
        printf("%lld\n",ans.R*q_pow((l-L)&1?(r-l+1)/2:(r-l+2)/2,mod-2,mod)%mod);
    }
    return 0;
}

T3 树状数组

两个关键性质:

  • 低 \(p\) 位均为 \(0\) 的所有数在进行同样后缀的操作后低 \(p\) 位相同。

  • 运算过程中,两个低 \(p\) 位均为 \(0\) 的时刻之间的 \(-1\) 操作不会影响到比 \(p\) 位更高的,也就是可以直接异或和。

考虑预处理 \(f_{p,i}\) 表示在 \(i\) 操作之后低 \(p\) 为均为 \(0\) 的数下一次低 \(p\) 为均为 \(0\) 的位置,\(g_{p,i,0/1}\) 表示在 \(i\) 操作之后低 \(p-1\) 位均为 \(0\) 且第 \(p\) 位为 \(0/1\) 的数下一次低 \(p\) 位均为 \(0\) 的位置。

预处理过程是倒序枚举,如果已经处理了 \(p-1\),那么 \(p\) 的只需讨论当前操作并在 \(g_{p,f_{p-1,i},0/1}\) 转移过来。

之后预处理 \(ans_i\) 表示 \(i\) 位置输入 \(0\) 后进行操作最终的结果。这个过程找到最大的 \(p\) 使得 \(f_{p,i}\) 存在,那么 \(ans_{f_{p,i}+1}\) 与 \(ans_i\) 相比,低 \(p\) 位都相同,剩下的不会被 \(-1\) 影响,直接异或和。

最后求答案考虑一次消去 \(\mathrm{lowbit}\),每次跳到 \(g_{p,i,1}\) 的位置,这个过程依旧是低位不变,高位异或和。最终到达的位置也是和 \(ans_i\) 处理即可。

点击查看代码
#define lowbit(x) (x&-x)

int n,m,k,A,B;
int a[maxn];
int xorsum[maxn];
int f[31][maxn],g[31][maxn][2];
int ans[maxn];
int lastans;

int main(){
    freopen("fenwick.in","r",stdin);
    freopen("fenwick.out","w",stdout);
    n=read(),m=read(),k=read(),A=read(),B=read();
    for(int i=1;i<=n;++i){
        a[i]=read();
        xorsum[i]=xorsum[i-1]^(a[i]==-1?0:a[i]);
    }
    f[0][n]=n+1,g[0][n][0]=n,g[0][n][1]=n+1,g[0][n+1][0]=n+1,g[0][n+1][1]=n+1;
    for(int i=n-1,last=(a[n]==-1||a[n]&1)?n:n+1;i>=0;--i){
        if(a[i+1]==-1||!(a[i+1]&1)) f[0][i]=i+1;
        else f[0][i]=g[0][i+1][1];
        g[0][i][0]=i,g[0][i][1]=last;
        if(a[i]==-1||a[i]&1) last=i;
    }
    for(int p=1;p<k;++p){
        f[p][n]=n+1,g[p][n][0]=n,g[p][n][1]=n+1,g[p][n+1][0]=n+1,g[p][n+1][1]=n+1;
        for(int i=n-1;i>=0;--i){
            if(a[i+1]==-1||lowbit(a[i+1])>(1<<p)) f[p][i]=i+1;
            else f[p][i]=g[p][f[p-1][i]][((xorsum[f[p-1][i]]^xorsum[i])>>p)&1];
            g[p][i][0]=i;
            if(a[i+1]==-1) g[p][i][1]=i+1;
            else g[p][i][1]=g[p][f[p-1][i]][((xorsum[f[p-1][i]]^xorsum[i])>>p)&1^1];
        }
    }
    for(int i=n;i>=1;--i){
        int high=-1;
        for(int p=k-1;p>=0;--p){
            if(f[p][i-1]!=n+1){
                high=p;
                break;
            }
        }
        if(high==-1) ans[i]=xorsum[n]^xorsum[i-1];
        else ans[i]=ans[f[high][i-1]+1]^(((xorsum[f[high][i-1]]^xorsum[i-1])>>high+1)<<high+1);
    }
    while(m--){
        int l=read(),x=read();
        l^=(1ll*A*lastans+B)%n,x^=(1ll*A*lastans+B)%(1<<k);
        --l;
        while(x){
            int low=__lg(lowbit(x));
            if(g[low][l][1]==n+1) break;
            x=((x>>low+1)<<low+1)^(((xorsum[g[low][l][1]]^xorsum[l])>>low+1)<<low+1);
            l=g[low][l][1];
        }
        if(!x) lastans=ans[l+1];
        else{
            int low=__lg(lowbit(x));
            lastans=(x>>low<<low)^ans[l+1];
        }
        printf("%d\n",lastans);
    }
    return 0;
}

标签:校国赛,考后,int,res,maxn,ans,Data,模拟,mod
From: https://www.cnblogs.com/SoyTony/p/Multiple_School_Simulation_Problems_of_NOI_in_July_3.htm

相关文章

  • 冲刺国赛模拟 36
    感觉思想都不难,但是场上不是想不出来就是写不动,见了鬼了。染色题考虑一个转化:对于奇数位置,在\(a_i\neqa_{i+2}\)的地方放一个红球,对于偶数位置在同样的地方放个蓝球。这样每个区间的限制变成\([l,r-2]\)不能同时有红蓝球,转移前缀和优化一下即可。#include<iostream>#inc......
  • [总结]2023-7-13A组模拟赛
    [总结]2023-7-13A组模拟赛P1心路历程发现今天的题目描述很直接,比昨天的好懂。然后发现T2似乎是数据结构,好像找到了归宿,心里踏实了一点。之后就发现自己不会的计数题但是有两道:T1和T3。T4还以为是板子题,然后发现读不懂。于是就开始干T2(终于不是从T1开始做了!!!),一开始以为要用高级......
  • HBuilder X连接MuMu模拟器指南
    一、运行MuMu模拟器查看服务端口16384二、adb环境变量配置找到HBuilderX的安装路径,进入如下目录,获取adb路径配置环境变量path添加adb路径三、adb连接端口打开cmd或者powershell窗口,执行如下命令adbconnect127.0.0.1:16384四、运行到模拟器测试设置adb......
  • vue 模拟滚动条循环滚动
    <template><el-cardclass="card-duty"><template#header><divclass="card-header"><span>重大警情</span></div></template>......
  • H3C 模拟器 防火墙开启Web功能
    环境windows10,模拟器 HCL_V5.9.0防火墙 1在windows添加虚拟网卡我的电脑--管理--设备管理器--网络适配器(选择)--操作--(添加过时硬件)--进入向导-下一步--搜索并自动安装--选择网络适配器-2给虚拟网卡配置ip如上图中所示3在防火墙命令行配置<H3C>system-view[H3C......
  • 如何实现ios电脑模拟器的具体操作步骤
    iOS电脑模拟器在开发iOS应用程序时,我们通常需要在真实设备上进行测试和调试。然而,有时我们可能没有设备可用,或者我们希望在不同的iOS版本上进行测试,这时就需要使用iOS电脑模拟器了。什么是iOS电脑模拟器iOS电脑模拟器是一种可以在Mac电脑上运行的虚拟设备,它模拟了真实iOS设备的......
  • NOIP 2023 模拟赛 20230712 C 论剑
    首先是伟大的题面然后是数据范围先解决1-4号数据点1.枚举每个gcd的值p,统计一次答案,得到最小值(期望得分20)\[ans=\min_{p=2}^{\maxa}\sum^n_{i=1}\min(a_i\bmodp,p-(a_i\bmodp)(a>p))\]2.我们可以发现p仅在为质数时不会重复,也可以将p换为质数(期望得分40)两种的时间复......
  • HHHOJ #1238. 「NOIP 2023 模拟赛 20230712 D」但战斗还未结束 思考--zhengjun
    赛时想写60pts,结果cxr似乎少算了一点空间,导致我一直没把空间卡过去QWQ。当时不会dfs求拓扑序,这里讲一下。枚举所有非访问过的点依次dfs,每次进行下列操作:找出\(v\)的一个未访问过的入点\(u\),调用dfs(u);找不到\(u\)的时候,把\(v\)加入拓扑序列中。代码#inc......
  • 数据结构与算法 #18 下跳棋,极富想象力的同向双指针模拟
    ⭐️本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]和[BaguTreePro]知识星球提问。学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭将基于Java/Kotlin语言,为你分享常......
  • 「NOIP 2023 模拟赛 20230711 B」过往未来
    summarization给定一个\(n\)个节点的树,定义\(x_1,x_2,\cdots,x_k\)生成的子树为树中边数最少的包含\(x_1,x_2,\cdots,x_k\)的连通块。对所有可能的\(x_1,x_2,\cdots,x_k\quad(1\lex_1<x_2<\cdots<x_k\len)\),求\(x_1,x_2,\cdots,x_k\)生成的子树的大小(边数和)总和。so......