首页 > 其他分享 >【考后总结】6 月西安多校模拟赛 4

【考后总结】6 月西安多校模拟赛 4

时间:2023-06-24 19:33:44浏览次数:41  
标签:考后 int 青蛙 maxw 多校 maxn freopen times 模拟

6.21 冲刺国赛模拟 22

T1 跳跃

不妨看作两只青蛙从相同起点出发且跳跃次数相同,设 \(f_{i,j,k}\) 为两只青蛙分别在 \(i,j\) 位置,且相差步数 \(k\)。由于需要记录相邻位置对答案贡献,我们在要求必须严格按照升序对处理状态,也就是必须保证当前跳跃的一只青蛙落点在另一只青蛙更前面,且靠后的青蛙可以也可以一步跳到或跳过靠前的一只,也就是 \(0\le i-j\le B\)。

考虑优化,设 \(i=a_i\times A+b_i\times B+C,j=a_j\times A+B_j\times B+C\),如果已知 \(i,a_i,a_j\),再结合 \(0\le i-j=(a_i-a_j)\times A+(b_i-b_j)\times B\le B\) 的特殊性质,就能计算出 \(i,j\),不放修改状态为 \(f_{i,j,k}\) 表示靠前的青蛙在 \(i\) 位置,其中两只青蛙分别跳 \(A\) \(j\) 或 \(k\) 次的最大答案。同时发现直接模 \(B\) 就是 \(i-j\),而对于 \(i-j=B\) 的情况,发现这个时候 \(j\) 由 \(i-B\) 到 \(i\) 是去到了两个去过的地方且 \(j,k\) 的值也没改变,所以不用考虑。

再优化,注意到 \(j,k\) 的用处实际是作为 \(j-k\) 整体,所以把状态改成 \(f_{i,j}\) 后者表示 \(a_i\) 与 \(a_j\) 的差,这样转移即可。

同时存在 \(i\) 不变,\(j\) 先跳到 \(i\) 然后再跳到后面的位置,因此第二维不能完全按下标顺序转移,需要把 \(i=j\) 的情况放最后。

点击查看代码
int n,A,B;
int c[maxn];
int f[maxn][maxw<<1];
vector<int> V;
int main(){
    freopen("jump.in","r",stdin);
    freopen("jump.out","w",stdout);
    n=read(),A=read(),B=read();
    for(int i=1;i<=n;++i) c[i]=read();
    memset(f,~0x3f,sizeof(f));
    for(int i=1;i<=B;++i) f[i][maxw]=0;
    for(int i=1;i<=A;++i) f[i-A+B][-1+maxw]=((i-A+B)-i)*(c[i-A+B]^c[i]);
    for(int i=1,j;i<=n;++i){
        V.clear();
        for(int k=-i/A-1;k<=i/A+1;++k){
            //i-j=(ai-aj)A+(bi-bj)B<=B
            j=i-(k*A%B+B)%B;
            if(i==j){
                V.push_back(k);
                continue;
            }
            if(i+A<=n&&j+B>=i+A){
                f[i+A][k+1+maxw]=max(f[i+A][k+1+maxw],f[i][k+maxw]+(i+A-i)*(c[i+A]^c[i]));
            }
            if(j+A<=n&&j+A>=i){
                f[j+A][-k+1+maxw]=max(f[j+A][-k+1+maxw],f[i][k+maxw]+(j+A-i)*(c[j+A]^c[i]));
            }
            if(j+B<=n&&j+B>=i){
                f[j+B][-k+maxw]=max(f[j+B][-k+maxw],f[i][k+maxw]+(j+B-i)*(c[j+B]^c[i]));
            }
        }
        for(int k:V){
            if(i+A<=n){
                f[i+A][k+1+maxw]=max(f[i+A][k+1+maxw],f[i][k+maxw]+(i+A-i)*(c[i+A]^c[i]));
                f[i+A][-k+1+maxw]=max(f[i+A][-k+1+maxw],f[i][k+maxw]+(i+A-i)*(c[i+A]^c[i]));
            }
            if(i+B<=n){
                f[i+B][k+maxw]=max(f[i+B][k+maxw],f[i][k+maxw]+(i+B-i)*(c[i+B]^c[i]));
                f[i+B][-k+maxw]=max(f[i+B][-k+maxw],f[i][k+maxw]+(i+B-i)*(c[i+B]^c[i]));
            }
        }
    }
    printf("%d\n",f[n][maxw]);
    return 0;
}

6.22 冲刺国赛模拟 23

T1 無言

原题:Gym102586-F Robots

容易发现编号相对应的去填是不劣的,于是一个球以其到对应位置的距离为半径,两侧的所有坑都要先被填满,相当于是一个区间对单点连边,进行拓扑排序。优化使用线段树优化建图。

点击查看代码
int n;
int a[maxn],b[maxn];
struct edge{
    int to,nxt;
}e[maxm];
int head[maxn*5],cnt;
int deg[maxn*5];
inline void add_edge(int u,int v){
    e[++cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
    ++deg[v];
}

queue<int> q;
ll ans;
int tot;
int pos[maxn];
map<int,int> mp;
struct SegmentTree{
#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
    void build(int rt,int l,int r){
        tot=max(tot,rt);
        if(l==r){
            pos[l]=rt;
            mp[rt]=l;
            return;
        }
        add_edge(rt<<1,rt),add_edge(rt<<1|1,rt);
        build(lson),build(rson);
    }
    void update(int rt,int l,int r,int pl,int pr,int p){
        if(pl<=l&&r<=pr){
            add_edge(rt,p);
            return;
        }
        if(pl<=mid) update(lson,pl,pr,p);
        if(pr>mid) update(rson,pl,pr,p);
    }
#undef mid
#undef lson
#undef rson
}S;

int main(){
    freopen("nameless.in","r",stdin);
    freopen("nameless.out","w",stdout);
    n=read();
    for(int i=1;i<=n;++i) a[i]=read();
    for(int i=1;i<=n;++i) b[i]=read();
    S.build(1,1,n);
    for(int i=1;i<=n;++i){
        int dis=abs(a[i]-b[i]);
        ans+=dis;
        if(a[i]<b[i]){
            //to left
            int l=i+1,r=lower_bound(a+1,a+n+1,2*b[i]-a[i])-a-1;
            if(r==i) continue;
            S.update(1,1,n,l,r,pos[i]);
        }
        else{
            //to right
            int l=lower_bound(a+1,a+n+1,2*b[i]-a[i])-a,r=i-1;
            if(l==i) continue;
            S.update(1,1,n,l,r,pos[i]);
        }
    }
    printf("%lld\n",ans);
    for(int i=1;i<=tot;++i){
        if(!deg[i]) q.push(i);
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        if(mp.count(u)) printf("%d ",mp[u]);
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].to;
            --deg[v];
            if(!deg[v]) q.push(v);
        }
    }
    printf("\n");
    return 0;
}

T2 排列

原题:Gym102586-I Amidakuji

\(k\) 有一个 \(\log\) 的限制,所以考虑倍增之类的做法,设 \(f_{i,j}\) 表示第 \(i\) 个排列中 \(j\) 置换到的数,那么可以以 \(f_{i,j}=j+2^{i-1}\) 为定义,如果是 \(f\) 的逆,那就是减去 \(2^{i-1}\),所以我们进行 \(k\) 次操作得到的应该是 \(\sum_{i=1}^k a_i2^{i-1}\),其中 \(a_i=\pm 1\),这样是可以取到所有 \((-2^k,2^k)\) 的奇数的,由于答案对 \(n\) 取模,且 \(2^k\ge n\),那么当 \(n\) 为奇数时,取模后可以取遍所有的数。

在此基础上考虑 \(n\) 是偶数,实际上从 \(x\) 到 \(y\) 在模意义下理论上最多只要增加或减少 \(\dfrac{n}{2}\) 就可以了,那么我们可以舍弃前两次置换来让 \(n\) 是偶数时成立。

注意到 \(n=2\) 是一定不行的,如果我们把 \(4\) 个相邻划为一组,那么需要奇偶性两个改变两个不变,同时需要其本身发生相对位置变化,从而求逆时变成另两个改变,这个时候 \((0,1,2,3)\) 变为 \((2,3,1,0)\) 即可,此时 \(0,1\) 奇偶性改变,且位置改变,这样求逆就是 \(2,3\) 奇偶性改变了,这就是 \(n\) 是 \(4\) 的倍数的情况。最后一种把最后 \(6\) 个划为一组,第一个排列对前 \(4\) 个做,第二个对后 \(4\) 个做就行了。


int n,k;

int main(){
    freopen("permutation.in","r",stdin);
    freopen("permutation.out","w",stdout);
    n=read();
    if(n==1) return printf("1\n0\n"),0;
    else if(n==2) return printf("-1\n"),0;
    k=__lg(n-1)+2;
    printf("%d\n",k);
    if(n&1){
        for(int i=1;i<=k;++i){
            for(int j=0;j<n;++j){
                printf("%d ",(j+(1<<i-1))%n);
            }
            printf("\n");
        }
    }
    else if(n%4==0){
        for(int j=0;j<n;++j){
            if(j%4<=1) printf("%d ",j+2);
            else if(j%4==2) printf("%d ",j-1);
            else printf("%d ",j-3);
        }
        printf("\n");
        for(int i=1;i<k;++i){
            for(int j=0;j<n;++j){
                printf("%d ",(j+(1<<i-1))%n);
            }
            printf("\n");
        }
    }
    else{
        for(int j=0;j<n-2;++j){
            if(j%4<=1) printf("%d ",j+2);
            else if(j%4==2) printf("%d ",j-1);
            else printf("%d ",j-3);
        }
        printf("%d %d\n",n-2,n-1);
        for(int j=0;j<n-4;++j) printf("%d ",j);
        printf("%d %d %d %d\n",n-2,n-1,n-3,n-4);
        for(int i=1;i<k-1;++i){
            for(int j=0;j<n;++j){
                printf("%d ",(j+(1<<i-1))%n);
            }
            printf("\n");
        }
    }
    return 0;
}

标签:考后,int,青蛙,maxw,多校,maxn,freopen,times,模拟
From: https://www.cnblogs.com/SoyTony/p/Multiple_School_Simulation_Problems_in_Xian_June_4.html

相关文章

  • [ARM 汇编]高级部分—性能优化与调试—3.4.3 使用模拟器进行调试与测试
    在ARM汇编程序开发过程中,使用模拟器(emulator)进行调试和测试是一种非常有效的方法。模拟器可以在不同的处理器上测试代码,帮助我们发现潜在的问题,并提供丰富的调试功能。本节将介绍如何使用QEMU(一个流行的开源模拟器)进行ARM汇编程序的调试和测试。安装QEMU首先,我们需要安装QEMU......
  • Unity3D:模拟类
    推荐:将NSDT场景编辑器加入你的3D工具链3D工具集:NSDT简石数字孪生模拟类设备模拟器提供模拟类,可用于测试响应设备模拟器中特定于设备的行为的代码。以下模拟类位于UnityEngine.Device命名空间中:应用屏幕系统信息这些模拟类具有与其常规UnityEngine命名空间对应项相同......
  • GPT-4零失误通关大厂模拟面试,offer拿到手软?与AGI首次接触
    “GPT-4可被视作AGI(通用人工智能)的早期版本。”如若从他人口中说出,或许是无稽之谈——但是由微软雷蒙德研究院机器学习理论组负责人万引大神SébastienBubeck与2023新视野数学奖得主RonenEldan、2023新晋斯隆研究奖得主李远志、2020斯隆研究奖得主YinTatLee等科学家共同撰写的......
  • 【杂题乱写】6 月西安多校 DP 专题训练
    这也太难了!这也太难了!这也太难了!AUOJ-607UR#20跳蚤电话加点操作太抽象,改成删点,每次可以删一个叶子,或者删一个只有一个父亲和一个儿子的节点。算方案还带顺序,子树间再算多重集组合数不方便,不如直接算任意顺序删点最后合法删完的概率。设\(f_u\)为按任意顺序删点删完\(u\)......
  • Unity3D:模拟器视图
    推荐:将NSDT场景编辑器加入你的3D工具链3D工具集:NSDT简石数字孪生模拟器视图“模拟器”视图在模拟的移动设备上显示应用程序。使用它来查看应用程序与该设备的屏幕形状、分辨率和方向的显示方式。模拟器视图的屏幕截图使用模拟器视图若要打开模拟器视图,请执行下列操作之一:......
  • 模拟赛碎碎念
    P1285队员分组模拟赛出了一道只用求较小的一个组的人数的这题。赛时编了一个时间复杂度卡满可能会被卡常的做法,大概是这样的:如果给定的图是完全图,那么答案就是\(\lfloor\frac{n}{2}\rfloor\),否则就一定存在点对\((u,v)\)满足\(u\),\(v\)之间没有边相连。将\(u\)塞进点集......
  • 如何实现带有颜色文本的日志框_使用HTMLEditor模拟
    如何实现带有颜色文本的日志框_使用HTMLEditor模拟HTMLEditor是一个强大的html编辑器,可以方便的编辑各种html元素并得到html文本。比之TextArea要强大很多,因为TextArea中所有的文本只能有一种样式。如果想要实现一个日志框,其中普通信息、警告信息、错误信息使用不同......
  • winform控件开发一之复合控件开发(1)模拟量显示1
    winform控件开发包括三种类型复合控件,又称为组合控件扩展控件自定义控件复合控件:复合控件,又称为组合控件,一般是将现有控件功能进行组合形成一个新的控件。举例:设计一个工控中常用的模拟量控件,可以显示变量的名称,变量值和单位,如下图所示 在这个复合空间中,左边使用一个l......
  • IS220PAICH2A 336A4940CSP11通用电气模拟输入输出模块
    IS220PAICH2A336A4940CSP11通用电气模拟输入输出模块IS220PAICH2A336A4940CSP11通用电气模拟输入输出模块  但是传统的以太网是一种商用网络,要应用到工业控制中还存在一些问题,主要有以下几个方面。1、存在实时性差,不确定性的问题传统的以太网采用了CSMA/CD的介质......
  • 西门子200PLC控制台达伺服电机正反转,步科触摸屏,模拟量控制;
    西门子200PLC控制台达伺服电机正反转,步科触摸屏,模拟量控制;实现功能如下:当前张力值小于设定值时,电机反转当前张力值大于设定值时,电机正转,当前张力值小于最小值或大于最大值时,电机停止运行,电机运行速度可以设定和显示。ID:326606175379560......