Codeforces Round #633 (Div. 2)题解(打表)

在这里插入图片描述

A. Filling Diamonds

F(n)=F(n-1)+1

B. Sorted Adjacent Differences

最左边,然后最右边,往返取

C. Powered Addition

假设二分的数量的K,从前往后,若当前数比前面的最大值小,那么有两种情况:

  • 2^K-1也就是说有的都填了,还不够,此时返回false
  • 可以,那么一定可以刚好布满
/*
 *  Author : Jk_Chen
 *    Date : 2020-04-17-10.55.11
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

int n;
LL a[maxn];

bool check(int mx){
    LL pre=a[1];
    rep(i,2,n){
        if(a[i]>=pre){pre=a[i];continue;}
        LL need=pre-a[i];
        if((1ll<<mx)-1<need)return 0;
        pre=max(pre,a[i]);
    }
    return 1;
}

int main(){
    int t=rd;
    while(t--){
        n=rd;
        rep(i,1,n)a[i]=rd;
        int l=0,r=35,ans=-1;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid))ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}

/*_________________________________________________________end*/

D. Edge Weight Assignment

选一个非叶子作为root。

一个结点的儿子有多个叶子时,最大值减去叶子数-1

最小值,当存在两个儿子一奇一偶则为3,否则为1

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-17-11.09.01
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

#define rep_e(i,p,u) for(int i=head[p],u=to[i];i;i=nex[i],u=to[i])
int head[maxn],to[maxn<<1],nex[maxn<<1],now;
void add(int a,int b){
    nex[++now]=head[a];head[a]=now;to[now]=b;
}
void init_edge(){
    memset(head,0,sizeof head);
    now=0;
}
/*_________________________________________________________edge*/
int siz[maxn],flag[maxn];
int ans1,ans2;
void dfs(int p,int fa){
    siz[p]=1;
    flag[p]=1;
    int sonstate=0;

    int numleave=0;
    rep_e(i,p,u){
        if(u==fa)continue;
        dfs(u,p);
        siz[p]+=siz[u];
        if(siz[u]==1)numleave++;
        sonstate|=flag[u];
    }
    if(numleave>1)ans2-=numleave-1;
    if(sonstate==3)ans1=3;
    else if(sonstate==1)flag[p]=2;
}

int deg[maxn];
int main(){
    int n=rd;
    rep(i,1,n-1){
        int a=rd,b=rd;
        add(a,b);add(b,a);
        deg[a]++;deg[b]++;
    }
    ans1=1,ans2=n-1;
    int rt;
    rep(i,1,n)if(deg[i]>1){rt=i;break;}
    dfs(rt,0);
    printf("%d %d\n",ans1,ans2);
    return 0;
}

/*_________________________________________________________end*/

E. Perfect Triples

打表,发现对于每3个数,第一个数是1,4-7,16-31,-64-127…

分析每一组的第一个数在二进制上,每2位为一个单位,00|00|00变为01|10|11变为10|11|01再变为11|01||10
在这里插入图片描述

我们得到这一组的第一个数,然后推出第2个和第3个

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-17-11.30.35
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

namespace check{
    vector<int>ans;
    bool vis[maxn];

    void find(int p){
        vis[p]=1;
        rep(i,p+1,10000){
            if(vis[i])continue;
            if(vis[p^i])continue;
            vis[i]=1;vis[p^i]=1;
            ans.pb(p);
            ans.pb(i);
            ans.pb(p^i);
            return;
        }
    }

    void Main(){
        rep(i,1,1000){
            if(!vis[i])find(i);
        }
        int i=0;
        for(auto P:ans){
            i++;
            bitset<15>num(P);
            cout<<num<<"   "<<P<<endl;
            if(i%3==0)printf("_____%d________\n",i/3);
        }
    }
}

void find(LL n){
    LL zu=(n+2)/3;
    LL mul=1;
    while(zu>mul){
        zu-=mul;
        mul*=4;
    }
    LL fi=mul-1+zu;
//    printf("fi=%lld\n",fi);
    bitset<63>Z(fi);
    LL index=(n-1)%3;
    rep(i,0,61){
        if(Z[i]==1&&Z[i+1]==0){
            if(index==1){
                Z.set(i+1);
                Z.reset(i);
            }
            else if(index==2){
                Z.set(i);
                Z.set(i+1);
            }
        }
        else if(Z[i]==0&&Z[i+1]==1){
            if(index==1){
                Z.set(i);
                Z.set(i+1);
            }
            else if(index==2){
                Z.set(i);
                Z.reset(i+1);
            }
        }
        else if(Z[i]==1&&Z[i+1]==1){
            if(index==1){
                Z.set(i);
                Z.reset(i+1);
            }
            else if(index==2){
                Z.reset(i);
                Z.set(i+1);
            }
        }
        i++;
    }
    LL ans=0;
    rep(i,0,62){
        if(Z[i])ans|=1ll<<i;
    }
    printf("%lld\n",ans);
}

int main(){
    int t=rd;
    while(t--){
        LL n=rd;
        find(n);
    }
//check::Main();
    return 0;
}

/*_________________________________________________________end*/

发布了790 篇原创文章 · 获赞 348 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/105577952
今日推荐