真实自闭。。场上两题1008,1012
1008: TDL
f
(
n
,
m
)
f(n,m)
f(n,m)代表与n互质且大于n的第m个数字,题目给出m,k,求满足
(
f
(
n
,
m
)
−
n
)
⊕
n
=
k
(f(n,m)-n)⊕n=k
(f(n,m)−n)⊕n=k的最小n。
把式子化一下:
f
(
n
,
m
)
=
k
⊕
n
+
n
f(n,m)=k⊕n+n
f(n,m)=k⊕n+n。
因为gcd(a+b,b)=gcd(a,b),所以此处
k
⊕
n
k⊕n
k⊕n是与n互质第m个数。注意到m小于等于100,所以
k
⊕
n
k⊕n
k⊕n的值不会太大,在[1,800]枚举这个值(这个范围内质数个数已经超过130个了),得到最小的n即可。如果没有满足的n,说明无解。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll inf = 0x3f3f3f3f3f3f3f3f;
ll k;
int m;
ll ans = inf;
int main()
{
int T;
cin>>T;
while(T--){
scanf("%lld%d",&k,&m);
ans = inf;
for(ll t = 1; t <=800; ++t){
ll n = k^t;
if(n == 0) continue;
if(__gcd(n, t) != 1) continue;
int cnt = 0;
for(ll i = 1; i <= t; ++i){
if(__gcd(i, n) == 1) cnt++;
if(cnt > m) break;
}
if(cnt == m) ans = min(ans, n);
}
if(ans == inf) printf("-1\n");
else printf("%lld\n", ans);
}
}
1012:Stay Real
给一个二叉树,每次拿走最大的叶子。用优先队列模拟即可。
#include <bits/stdc++.h>
#define ll long long
#define P pair<ll,int>
using namespace std;
const int maxn=1e5+10;
int n;
ll a[maxn];
int in[maxn];
priority_queue<P> q;
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(a,0,sizeof a);
scanf("%d",&n);
for(int i=1; i<=n; ++i){
scanf("%lld",&a[i]);
in[i]=2;
bool ff=0;
if((i<<1)>n){ff=1;in[i]--;}
if((i<<1|1)>n) in[i]--;
if(ff) q.push(P(a[i],i));
}
bool flag=1;
ll ans1=0,ans2=0;
while(!q.empty()){
P tmp=q.top(); q.pop();
if(flag) ans1+=tmp.first;
else ans2+=tmp.first;
int pos;
if(tmp.second%2) pos=(tmp.second-1)/2;
else pos=tmp.second/2;
in[pos]--;
if(!in[pos]) q.push(P(a[pos],pos));
flag=!flag;
}
printf("%lld %lld\n",ans1,ans2);
}
}