zoukankan      html  css  js  c++  java
  • Codeforces Round 563 (Div. 2) 题解

    自己开了场镜像玩。

    前三题大水题。D有点意思。E完全不会。F被题意杀了……然而还是不会。

    不过看过(且看懂)了官方题解,所以这里是六题题解齐全的。


    A

    水题。给原序列排序,如果此时合法则直接输出,否则说明所有数相同,一定无解。

    时间复杂度 $O(nlog n)$。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=100010;
    #define MP make_pair
    #define PB push_back
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline ll read(){
        char ch=getchar();ll x=0,f=0;
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,a[maxn],s1,s2;
    int main(){
        n=read();
        FOR(i,1,2*n) a[i]=read();
        sort(a+1,a+2*n+1);
        FOR(i,1,n) s1+=a[i];
        FOR(i,n+1,2*n) s2+=a[i];
        if(s1==s2) printf("-1
    ");
        else FOR(i,1,2*n) printf("%d ",a[i]);
    }
    View Code

    B

    水题。

    首先,如果所有数的奇偶性都相同,那我们什么都不能做。

    否则,如果两个数奇偶性不同,可以直接交换;如果两个数奇偶性相同,可以用一个奇偶性不同的作为中介交换。那么实际上就是任意两个数都能交换,排个序即可。

    时间复杂度 $O(nlog n)$。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=100010;
    #define MP make_pair
    #define PB push_back
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline ll read(){
        char ch=getchar();ll x=0,f=0;
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,a[maxn];
    bool hhh[2];
    int main(){
        n=read();
        FOR(i,1,n) a[i]=read(),hhh[a[i]&1]=true;
        if(hhh[0] && hhh[1]) sort(a+1,a+n+1);
        FOR(i,1,n) printf("%d ",a[i]);
    }
    View Code

    C

    水题。

    首先质数位置的值互不相同。一一编号即可。

    对于合数(设为 $x$),可以任取它的一个质因子(设为 $p$),令 $a_x=a_p$。此时序列最大值不变,而两个互质的数的位置的值不可能相同。

    我取的是最小质因子。

    时间复杂度 $O(n)$。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=100010;
    #define MP make_pair
    #define PB push_back
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline ll read(){
        char ch=getchar();ll x=0,f=0;
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,ans[maxn],pr[maxn],mn[maxn],pl,cnt;
    bool vis[maxn];
    int main(){
        n=read();
        FOR(i,2,n){
            if(!vis[i]) pr[++pl]=i,ans[i]=++cnt;
            FOR(j,1,pl){
                if(i*pr[j]>n) break;
                vis[i*pr[j]]=true;
                mn[i*pr[j]]=pr[j];
                if(i%pr[j]==0) break;
            }
        }
        FOR(i,2,n) if(mn[i]) ans[i]=ans[mn[i]];
        FOR(i,2,n) printf("%d ",ans[i]);
    }
    View Code

    D

    有一点点小难度,但还是很水。

    首先考虑这个序列的前缀异或和 $S$。那么对于任意的 $i$,有 $S_i e x$;对于任意的 $i,j$($i e j$),有 $S_ioplus x e S_j$。

    看第二条限制,发现如果选了 $a$,那么不能选 $aoplus x$;如果选了 $aoplus x$,那么不能选 $a$。对其它数没有影响。

    所以可以在 $a,aoplus x$ 中任选一个作为前缀异或和。

    最后用选出来的前缀异或和算出原序列。此时答案一定是最优。

    时间复杂度 $O(2^n)$。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int maxn=333333;
    #define MP make_pair
    #define PB push_back
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline ll read(){
        char ch=getchar();ll x=0,f=0;
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,x,lim,ans[maxn],al;
    bool vis[maxn];
    int main(){
        n=read();x=read();
        lim=1<<n;
        FOR(i,1,lim-1){
            if(vis[i^x] || i==x) continue;
            vis[i]=true;
            ans[++al]=i;
        }
        printf("%d
    ",al);
        FOR(i,1,al) printf("%d ",ans[i]^ans[i-1]);
    }
    View Code

    E

    太难了……难度 2500……

    为此专门另开了篇博客:传送门


    F

    一开始以为不会给树的形态,一直在想……

    这里给出轻重链剖分(俗称树剖)的做法。

    首先一开始肯定要查询 $1$ 到 $x$ 的距离。这个就是 $x$ 的深度 $dep_x$。(定义 $1$ 的深度为 $0$)

    现在假设我们已经确定 $x$ 在 $u$ 的子树中。一开始 $u=1$。

    我们沿着 $u$ 的重儿子一直跳,跳到叶子结点 $v$。(实际上不用真跳,可以实现成 $O(1)$)

    接下来,再考虑 $y=lca(x,v)$。(从官方题解盗张图)

    首先,询问一次 $dis(x,v)$。由于 $dis(x,v)=dep_x+dep_v-2dep_y$,而 $dis(x,v)$ 已知,$dep_x$ 已知,$dep_v$ 已知,可以算出 $dep_y$。那么 $y$ 也已知。

    如果 $dep_x=dep_y$ 那么 $x=y$。 否则我们再询问 $y$ 到 $x$ 路径上的第二个点 $www$(没名字了),然后接下来就可以在 $u=www$ 的子树中寻找答案了。

    对于最后一次查找,只用 $1$ 次询问,其它要 $2$ 次询问。预处理 $dep_x$ 要 $1$ 次询问。由于 $sz[www]le sz[y]/2le sz[u]$,所以每次 $u$ 的大小都会缩小一半。

    那么总共要 $2log n$ 次询问。时间复杂度 $O(n)$。

    代码咕着,会来补的。

  • 相关阅读:
    多线程之同步代码块与同步函数
    图片上传客户端与服务端
    tcp上传学习二--文本文件上传
    javaScript编写9*9口诀
    tcp聊天
    udp聊天室--简易
    往sencha.cmd中恢复设计项时,不论是系统的还是应用的,恢复进去之后都应该一键发布到前端
    一个设计项上的按钮调另一个设计项的列表界面,同时加筛选条件
    点击【****】设计项上的某个按钮,直接调出另一个设计项的【编辑界面】
    前端向后端发送请求,后端返回的一个值的请求的ajax.get();方法
  • 原文地址:https://www.cnblogs.com/1000Suns/p/10987316.html
Copyright © 2011-2022 走看看