CF Round #580(div2)题解报告

T1 T2

水题,不管

T3

构造题,证明大约感性理解一下

我们想既然存在解

\(|a[n + i] - a[i]| = 1\)

这是必须要满足的

既然这样,那么图必须是这样的

\(-\),是相邻的两个数中的较小的一个,\(+\)是相邻的两个数中较大的

这样分配是肯定有解的

但是当n时偶数的时候,手玩一下就会发现,不可能满***替,所以无解

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
inline int read(){
    int v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') c = -1;
        ch = getchar();
    }
    while(isdigit(ch)){
        v = v * 10 + ch - 48;
        ch = getchar();
    }
    return v * c;
}
const int N = 5e5 + 3;
int a[N];
int n;
int main(){
    n = read();
    if(n & 1){
        int now = 0;
        for(int i = 1;i <= n;++i){
            if(!now) a[i] = i * 2 - 1,a[i + n] = i * 2;
            else a[i] = i * 2,a[i + n] = i * 2 - 1;
            now ^= 1;
        }
        printf("YES\n");
        for(int i = 1;i <= 2 * n;++i) printf("%d ",a[i]);  
    }   
    else printf("NO\n");
    return 0;
}

T4

分位考虑

这道题的关键在于给你张图,求最小环

由于点数和边数特别少,所以直接爆搜就好了

但是考虑多项式做法

最小环的本质是对于边\((u,v)\),去掉边后\((u,v)\)的最短路径\(+1\)

这可以在floyd的过程中搞一搞

当然,这是在边有边权的前提下
这道题目直接枚举每一条边然后bfs就好了

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
const int INF = 0x3f3f3f3f;
using namespace std;
inline LL read(){
    LL v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch)){
        if(ch == '-') c = -1;
        ch = getchar();
    }
    while(isdigit(ch)){
        v = v * 10 + ch - 48;
        ch = getchar();
    }
    return v * c;
}
const int N = 2e5 + 3;
LL a[N];
int n,ans;
int xx[65],yy[65];
int tot,rt;
struct edge{
    int to;
    int from;
    int nxt;    
}e[N << 1];
int head[N];
int deep[N],fa[N];
int book[N];
int vis[N];
inline void add(int x,int y){
    e[++tot].to = y;
    e[tot].nxt = head[x];
    e[tot].from = x;
    head[x] = tot;
}
inline void dfs(int x,int dep){
//  book[x] = 1;
    vis[x] = 1;
    for(int i = head[x];i;i = e[i].nxt){
        int y = e[i].to;
        if(y == rt && dep > 2) ans = min(ans,dep);
        else if(!vis[y]) dfs(y,dep + 1);
    }
    vis[x] = 0;
}
int main(){
    //freopen("A.in","r",stdin);
    //freopen("A.out","w",stdout);
    n = read();
    for(int i = 1;i <= n;++i) a[i] = read();
    for(int i = 0;i <= 62;++i){
        int sum = 0;
        for(int j = 1;j <= n;++j){
            if(a[j] & (1ll << i)){
                if(!xx[i]) xx[i] = j;
                else if(!yy[i]) yy[i] = j;
                sum++;
                if(sum == 3){
                    printf("3\n");
                    return 0;   
                }
            }
        
        }
        if(sum == 2) add(xx[i],yy[i]),add(yy[i],xx[i]);//printf("%d %d\n",xx[i],yy[i]);
    }
    ans = INF;
    for(int i = 1;i <= n;++i){
        dfs(rt = i,1);
        if(ans == 3){
            printf("3\n");return 0; 
        }
    }
    if(ans > n) printf("-1\n");
    else printf("%d\n",ans);
    return 0;
}