zoukankan      html  css  js  c++  java
  • 【考试反思】联赛模拟测试15

    建议改成:凯爹吊打 std

    凯爹被卡常了,可恶啊。

    基础篇,但成功暴露了基础很薄弱。T4 LCIS 完全没思路。

    T1: 90 ( ightarrow) 80

    T1:游戏

    对自己暴力太自信了,想数据点分治,但显然 (O(10!cdot 10)) 显然是跑不过 500ms的 = =。

    其实也不好意思说是挂分,因为是乱搞的水了很多分。对拍大概每 3000,4000 组就挂了,但是数据太水,就很偷税

    正解是和之前的哪一天她能重回我身边类似,但没有疾患鼠的情况所以更简单。同样两个值连边,统计联通块大小。以上口胡的

    正解是并查集。一个装备的两个属性连到并查集里,如果并查集构成了一个环,那么这个并查集是可以都选的。如果并查集构成了一棵树,那么这个并查集除了最大的数都可以选。

    从一开始循环选就好了,当选不了了就 break。(%%% HISKrrr

    Code
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    int n,ans;
    
    inline int read(){
        int x=0;bool fopt=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-')fopt=0;
        for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
        return fopt?x:-x;
    }
    
    int fa[maxn],siz[maxn];
    bool flag[maxn];//判断是否为环
    int Find(int x){
        return x==fa[x]?x:(fa[x]=Find(fa[x]));
    }
    
    int main(){
    #ifndef LOCAL
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
    #endif
        n=read();
        for(int i=1;i<=10000;i++){
            fa[i]=i;
            siz[i]=1;
        }
        for(int i=1;i<=n;i++){
            int x=read(),y=read();
            int fax=Find(x),fay=Find(y);
            if(fax==fay){
                flag[fax]=1;
            }else{
                fa[fax]=fay;
                siz[fay]+=siz[fax];
                flag[fay]|=flag[fax];
            }
        }
        for(int i=1;i<=10000;i++){
            int fai=Find(i);
            if((flag[fai]&&siz[fai]>0)||siz[fai]>1){
                ans++;siz[fai]--;
            }else break;
        }
        printf("%d
    ",ans);
        return 0;
    }
    

    T2:嘟嘟噜

    约瑟夫问题,但显然线性是过不去的。

    打表发现(建议 (m)(4),很容易找到规律),只有过了一段区间之后才会出现取模的情况,那就是目前的值比下标大的时候。那么我们显然可以计算出下次跳到需要取模的位置,中间直接乘法加上。

    设下一次需要跳 (x) 步,目前的值是 (a),那么可以得到:

    [i+x<a+m imes x ]

    首先注意一定是小于,因为正好相等的时候是不能取模的,因为实际上正好相等的时候对应到 (0) ~ (n-1) 的编号是比下标小的。

    简单移项改等号解得:

    [x=igglceil cfrac{i-a}{m-1} igg ceil ]

    那么下次的下标就是 (i+x)。相等的时候需要特判一下,懂的都懂。

    最后剩下的部分直接加上就好了。小于 (m) 的部分直接暴力。

    时间复杂度 (O(能过))

    当然前提是你要会线性解决约瑟夫问题的式子,可以看前几天的那道题。

    UPD:现在我发现在一开始如果不 (+1) 的话就不用特判了 orz

    Code
    #include <bits/stdc++.h>
    using namespace std;
    
    inline int read(){
        int x=0;bool fopt=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-')fopt=0;
        for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
        return fopt?x:-x;
    }
    
    int main(){
    #ifndef LOCAL
        freopen("mayuri.in","r",stdin);
        freopen("mayuri.out","w",stdout);
    #endif
        int T=read();
        while(T--){
            int n=read(),m=read(),x=0,i=m;
            for(register int j=2;j<=min(n,m);j++){
                x=(x+m)%j;
            }
            if(n<=m)printf("%d
    ",x+1);
            else{
                x+=1;//记得+1!
                while(1){
                    int nxt=i+(int)ceil(1.0*(i-x)/(m-1));
                    if(nxt>n)break;
                    x=(x+(nxt-i)*m);
                    if(x==nxt){
                        if(++nxt>n)break;
                        x=(x+m)%nxt;
                    }else x%=nxt;
                    i=nxt;
                }
                x+=(n-i)*m;
                printf("%d
    ",x);
            }
        }
        return 0;
    }
    

    T3:天才绅士少女助手克里斯蒂娜

    好像直接改改式子,就能用线段树单点修改区间求和了。但是 T2 调了太久,所以本题 10 min 走人 = =。

    [egin{aligned} sumlimits_{lleq i<jleq r}vert v_i imes v_jvert^2&= sumlimits_{lleq i<jleq r}(x_iy_j-x_jy_i)^2\ &=sumlimits_{lleq i<jleq r}x_i^2y_j^2-2 imes x_iy_ix_jy_j+x_j^2y_i^2\ &=sumlimits_{i=l}^rsumlimits_{j=l}^r x_i^2y_j^2-x_iy_ix_jy_j\ &=igg(sumlimits_{i=l}^rx_i^2igg) imes igg(sumlimits_{i=l}^ry_i^2igg)-igg(sumlimits_{i=l}^rx_iy_iigg)^2\ end{aligned}]

    直接开线段树维护 (x^2)(y^2)(xy) 即可。

    不开 long long 见祖宗

    Code
    #include <bits/stdc++.h>
    using namespace std;
    int n,m;
    long long X2,Y2,XY;
    const int Mod=20170927;
    const int maxn=1e6+10;
    
    inline int read(){
        int x=0;bool fopt=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-')fopt=0;
        for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
        return fopt?x:-x;
    }
    
    struct Node{
        long long x,y;
    }v[maxn];
    
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    struct SEG{
        long long x2,y2,xy;
    }tree[maxn<<2];
    
    inline void pushup(int rt){
        tree[rt].x2=(tree[lson].x2+tree[rson].x2)%Mod;
        tree[rt].y2=(tree[lson].y2+tree[rson].y2)%Mod;
        tree[rt].xy=(tree[lson].xy+tree[rson].xy)%Mod;
    }
    
    void build(int rt,int l,int r){
        if(l==r){
            tree[rt].x2=(v[l].x*v[l].x)%Mod;
            tree[rt].y2=(v[l].y*v[l].y)%Mod;
            tree[rt].xy=(v[l].x*v[l].y)%Mod;
            return;
        }
        int mid=(l+r)>>1;
        build(lson,l,mid);build(rson,mid+1,r);
        pushup(rt);
    }
    
    void modify(int rt,int l,int r,int p,long long x,long long y){//这的x和y也要开long long!
        if(l==r){
            tree[rt].x2=(x*x)%Mod;
            tree[rt].y2=(y*y)%Mod;
            tree[rt].xy=(x*y)%Mod;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid)modify(lson,l,mid,p,x,y);
        else modify(rson,mid+1,r,p,x,y);
        pushup(rt);
    }
    
    void query(int rt,int l,int r,int s,int t){
        if(s<=l&&r<=t){
            X2=(X2+tree[rt].x2)%Mod;
            Y2=(Y2+tree[rt].y2)%Mod;
            XY=(XY+tree[rt].xy)%Mod;
            return;
        }
        int mid=(l+r)>>1;
        if(s<=mid)query(lson,l,mid,s,t);
        if(t>mid)query(rson,mid+1,r,s,t);
    }
    
    int main(){
    #ifndef LOCAL
        freopen("kurisu.in","r",stdin);
        freopen("kurisu.out","w",stdout);
    #endif
        n=read();m=read();
        for(int i=1;i<=n;i++){
            v[i].x=read();v[i].y=read();
        }
        build(1,1,n);
        while(m--){
            int opt=read();
            if(opt==1){
                int p=read(),x=read(),y=read();
                modify(1,1,n,p,x,y);
            }else{
                int l=read(),r=read();
                X2=Y2=XY=0;
                query(1,1,n,l,r);
                printf("%lld
    ",((X2*Y2%Mod-(XY*XY)%Mod)%Mod+Mod)%Mod);
            }
        }
        return 0;
    }
    

    T4:凤凰院凶真

    LCIS 并输出方案,爷不会(wtcl)。

    奉上金牌教练老姚版 LCIS:

    Code
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=5e3+10;
    int n,m;
    int a[maxn],b[maxn];
    int f[maxn][maxn],pre[maxn][maxn];
    
    inline int read(){
        int x=0;bool fopt=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-')fopt=0;
        for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
        return fopt?x:-x;
    }
    
    void Print(int x,int y){
        if(!x)return;
        Print(x-1,pre[x][y]);
        if(f[x][y]!=f[x-1][pre[x][y]])
            printf("%d ",b[y]);
    }
    
    int main(){
    #ifndef LOCAL
        freopen("phoenix.in","r",stdin);
        freopen("phoenix.out","w",stdout);
    #endif
        n=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        m=read();
        for(int i=1;i<=m;i++)
            b[i]=read();
        for(int i=1;i<=n;i++){
            int Max=0,k=0;
            for(int j=1;j<=m;j++){
                f[i][j]=f[i-1][j];pre[i][j]=j;
                if(a[i]>b[j]&&Max<f[i-1][j]){
                    Max=f[i-1][j];k=j;
                }
                if(a[i]==b[j]){
                    f[i][j]=Max+1;pre[i][j]=k;
                }
            }
        }
        int now=0;
        for(int i=1;i<=m;i++)
            if(f[n][i]>f[n][now])now=i;
        printf("%d
    ",f[n][now]);
        Print(n,now);
        puts("");
        return 0;
    }
    
  • 相关阅读:
    记一次线上OOM问题分析与解决
    理解JAVA内存模型
    SpringBoot+Shiro+JPA+LayUI的后台管理系统
    学会使用BeanUtils,提高你的开发效率
    一篇文章教你快速上手接口管理工具swagger
    js 多维数组转一维数组(根据字段展示)
    记一次阿里云服务器中部署egg遇到的问题 (docker vim)
    react 封装tab组件
    js 添加 好玩的注释
    js 下载文件流
  • 原文地址:https://www.cnblogs.com/Midoria7/p/13807834.html
Copyright © 2011-2022 走看看