题目大意:
构造一个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.youkuaiyun.com/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 printf
const 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;
}
本文解析了多个算法题目,包括寻找序列中特定位置的数值、解决分数等式的整数解以及最大子树和的问题。提供了高效算法实现,并通过代码示例展示了如何优化算法以达到更好的性能。
460

被折叠的 条评论
为什么被折叠?



