CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!)
A - Good Pairs
- 签到~
#include <bits/stdc++.h>
#define int long long
#define Pa pair<int,int>
using namespace std;
const int N=1e5+5;
struct node
{
int x,id;
bool operator < (const node &b) const {return x<b.x; }
}a[N];
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) scanf("%lld",&a[i].x),a[i].id=i;
if(n==1) cout<<1<<' '<<1<<"\n";
else
{
sort(a+1,a+1+n);
cout<<a[1].id<<' '<<a[n].id<<"\n";
}
}
signed main()
{
int T=1;
cin>>T;
while(T--) solve();
}
B - Subtract Operation
分析:
-
结论题
取a[l] a[r],若将区间 (l,r) 之间的数一个一个数移除,最后余下的为 a [ r ] − a [ l ] o r a [ l ] − a [ r ] a[r]-a[l]\ or\ a[l]-a[r] a[r]−a[l] or a[l]−a[r]
再推广一下,发现任意两个数的差值都能得到
-
打个map标记一下即可
#include <bits/stdc++.h>
#define int long long
#define Pa pair<int,int>
using namespace std;
const int N=2e5+5;
int a[N];
map <int,int> mp;
void solve()
{
int n,k;
cin>>n>>k;
mp.clear();
for(int i=1;i<=n;i++) scanf("%lld",&a[i]), mp[a[i]]++;
for(auto it : mp)
{
int v=k+it.first;
if(mp.count(v))
{
cout<<"YES\n";
return ;
}
}
cout<<"NO\n";
}
signed main()
{
int T=1;
cin>>T;
while(T--) solve();
}
C - Make Equal With Mod
分析:
- 分类讨论
- 没有1:则从大到小变换,能够全部变成0
- 有1:要成立,则要全部变成1(若还有0就直接不成立了),若存在差值为1的两个数也是不成立的
#include <bits/stdc++.h>
#define int long long
#define Pa pair<int,int>
using namespace std;
const int N=2e5+5;
int a[N],b[9];
map <int,int> mp;
void solve()
{
int n,k;
cin>>n;
for(int i=0;i<=5;i++) b[i]=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(a[i]<=5) b[a[i]]++;
}
sort(a+1,a+1+n);
if(a[1]==a[n]) { cout<<"YES\n"; return; }
else
{
if((b[1] && b[0])) { cout<<"NO\n"; return; }
if(b[1])
{
for(int i=2;i<=n;i++) if(a[i]-a[i-1]==1) { cout<<"NO\n";return ;}
}
}
cout<<"YES\n";
}
signed main()
{
int T=1;
cin>>T;
while(T--) solve();
}
D - K-good
分析:
-
推式子+分类讨论+分解因数
n − ( k + 1 ) k / 2 ≡ 0 ( m o d k ) n-(k+1)k/2\equiv 0(mod \ k) n−(k+1)k/2≡0(mod k)因为a[i]>0,所以不是 ( k − 1 ) k / 2 (k-1)k/2 (k−1)k/2
-
可以看出要分两类:
- k为奇数:则k为n的因数
- k为偶数:则 k 2 \frac{k}{2} 2k为n的因数
#include <bits/stdc++.h>
#define int long long
#define Pa pair<int,int>
#define yes cout<<"YES\n";
#define no cout<<"NO\n";
using namespace std;
const int N=1e5+5;
void solve()
{
int n;
cin>>n;
int k=n;
while(k%2==0) k/=2;
// k取奇数
if(k!=1 && k<=2e9 && k*(k+1)/2<=n) { cout<<k<<"\n"; return; }
// k取偶数
k=n/k;
if(k<=1e9 && k*(2*k+1)<=n) {cout<<2*k<<"\n"; return; }
cout<<"-1\n";
}
signed main()
{
int T=1;
cin>>T;
while(T--) solve();
}
E - Equal Tree Sums
分析:
-
神仙思维+树上问题+结论
如果没有 a i ! = 0 a_i!=0 ai!=0的条件,直接全取0就是
现在有这个条件,想办法往这个条件构造
考虑树上的任意一条边的两个端点,往0靠,则正负取,即黑白染色
-
每个点的权值取其度数
这样就能保证这一整颗树(无根树)的权值为0,任意去掉一个“根节点”
- 若根为正:则剩下的子树的权值和都是为-1
- 若根伟负:则剩下的子树的权值和都是为1
#include <bits/stdc++.h>
#define int long long
#define Pa pair<int,int>
using namespace std;
const int N=2e5+5;
int a[N],b[100005];
vector <int> g[N];
int ans[N];
void dfs(int u,int fa,int fg)
{
ans[u]=fg*g[u].size();
for(int v : g[u])
{
if(v==fa) continue;
dfs(v,u,-fg);
}
}
void solve()
{
int n,k;
scanf("%lld",&n);
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,-1,1);
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
cout<<"\n";
}
signed main()
{
int T=1;
cin>>T;
while(T--) solve();
}