Codeforces Round #384 (Div. 2) B ,C ,D(规律,数学。树dp)

来源:互联网 发布:john carmack 知乎 编辑:程序博客网 时间:2024/06/06 00:27
题目大意:构造一个1213121412131215121312141213121…输入n,k,求k位置的数。 然后现在问你k位置是什么

B题

  第i个数是多少,就是i的质因数分解中2的幂次是多少。当然也可以递归做
  推了一下发现和n无关一个长度很长的序列构造肯定不行,每次对除以二直到第一次不能整除。

int main(){    LL len=0;    LL n,k;cin>>n>>k;    rep(i,1,n)len=len*2+1;    LL kk=k;    for(int i=n;i>=1;--i){        len=len/2;        if(kk==len+1){            pf("%d\n",i);return 0;        }        if(kk>len)kk-=len+1;    }}

大神的理解:实际上就是这个数字k的二进制最小的1的位数的位置。

    #include<bits/stdc++.h>      using namespace std;      long long n,p;      int main()      {          scanf("%lld%lld",&n,&p);          cout<<log2(p&(-p))+1<<endl;      }  

参考http://blog.csdn.net/qq_31917799/article/details/53957864

大概意思就是给一个整数n,找到三个不同的整数x,y,z,使得2/n = 1/x + 1/y + 1/z成立。分析下,一般容易想到令其中一个数为n,因为 2/n = 1/n + 1/n,这样我们只要找到x,y满足 1/n = 1/x + 1/y。我们只要找到合理的x,y即可。由 1/n = 1/x + 1/y 可得到     y = n*x/(x - n),要使得y为整数,令分母为1就可以了,所以,x = n + 1,这个时候 y = n * ( n + 1 ),当n为1时, x = y,要输出-1。
    #include <iostream>      using namespace std;      int main ()      {          int n;          cin >> n;          if (n > 1)              cout << n << " " << n + 1 <<" "<< (n + 1)*n << endl;          else cout << "-1" << endl;          return 0;      }  

D. Chloe and pleasant prizes

题目大意:已知一颗以1为根的树,让你找两个不相交的子树,使其和最大,如果找不到满足条件的解,输出Impossible
int n;int a[N];LL ans;LL dp[N];int fst[N],nxt[N<<1],vv[N<<1],e;void add(int u,int v){    vv[e]=v;nxt[e]=fst[u];fst[u]=e++;}LL sum[N];void dfs(int u,int p){    LL tmp=0;    for(int i=fst[u];~i;i=nxt[i]){        int v=vv[i];        if(v==p)continue;        dfs(v,u);        tmp+=sum[v];        ans=max(ans,dp[u]+dp[v]);        dp[u]=max(dp[u],dp[v]);    }    sum[u]+=tmp;    sum[u]+=a[u];    dp[u]=max(dp[u],sum[u]);    //dp[u]=max(dp[u]+a[u],tmp+a[u]);}int in[N];int main(){    //ree    sf("%d",&n);    mem(fst,-1);e=0;    rep(i,1,n)sf("%d",&a[i]);    rep(i,1,n-1){        int u,v;sf("%d%d",&u,&v);        add(u,v);add(v,u);        in[u]++;    }    ans=-inf;    for(int i=1;i<=n;++i)dp[i]=-100*INF;    dfs(1,1);    if(ans==-inf)puts("Impossible");    else cout<<ans<<'\n';}
//别人的做法。#include<bits/stdc++.h>using namespace std;#define LL long long#define MP(a,b) make_pair(a,b)#define mem(a,b) memset(a,b,sizeof(a))#define REP(i,a,b) for(int i=a;i<=b;++i)#define FOR(i,a,b) for(int i=a;i<b;++i)#define pii pair<int,int>#define sf scanf#define pf printfconst int maxn = 2e5;int n, pre[maxn+5];vector<int> G[maxn+5];LL arr[maxn+5], sum[maxn+5];char fg = 0;LL ans;LL dfs1(int x, int pp){    pre[x] = pp, sum[x] = arr[x];    for(int i=0; i<G[x].size(); ++i)        if(G[x][i] != pp)            sum[x] += dfs1(G[x][i], x);    return sum[x];}LL dfs2(int x){    vector<LL> tmp;    LL res = sum[x];    for(int i=0; i<G[x].size(); ++i)    {        if(G[x][i] != pre[x])            tmp.push_back( dfs2(G[x][i]) );    }    int sz = tmp.size();    if(sz == 0) return res;    if(sz >= 2)    {        sort(tmp.begin(), tmp.end());        if(fg==0 || tmp[sz-1]+tmp[sz-2]>ans)            fg = 1, ans = tmp[sz-1]+tmp[sz-2];    }    return max(res, tmp[sz-1]);}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int u, v;    sf("%d", &n);    REP(i,1,n) sf("%lld", arr+i);    FOR(i,1,n)    {        sf("%d%d", &u, &v);        G[u].push_back(v);        G[v].push_back(u);    }    dfs1(1, 0);    dfs2(1);    if(fg) pf("%lld\n", ans);    else pf("Impossible\n");    return 0;}
阅读全文
0 0