“爷爷,你关注的up主要更新拉!”
今天起开始CF/At不定期更新
A. Sum(暴力)
只需判断a,b,c是否为和关系即可
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll n;
ll a[Ma];
void sol()
{
for (ll i=0;i<3;i++)
scanf("%lld",&a[i]);
sort(a,a+3);
if (a[0]+a[1]==a[2])
printf("YES\n");
else
printf("NO\n");
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}
B. Increasing(sort+暴力)
只需判断有无重复数即可
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll n;
ll a[Ma];
void sol()
{
scanf("%lld",&n);
for (ll i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+n+1);
for (ll i=1;i<n;i++)
{
if (a[i]==a[i+1])
{
printf("NO\n");
return;
}
}
printf("YES\n");
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}
C. Stripes(思维)
只需判断一条贯穿即可,因为最后画图一定会有一条完整的线
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll n=8;
string s[Ma];
void sol()
{
for (ll i=0;i<n;i++)
cin>>s[i];
for (ll i=0;i<n;i++)
{
ll flag=0;
for (ll j=0;j<n;j++)
if (s[i][j]!='R')
flag=1;
if (!flag)
{
printf("R\n");
return;
}
}
printf("B\n");
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}
D. Coprime(思维)
我们可以发现ai<=1000,因此我们可以通过值匹配完成,复杂度为O()[M=1000](log为gcd复杂度)
PS:应该是有更加优秀的算法的,但是这题没必要(doge)
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define N 1005
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll n;
ll a[Ma];
ll f[Ma];
void sol()
{
scanf("%lld",&n);
memset(f,0,sizeof(f));
for (ll i=1;i<=n;i++)
scanf("%lld",&a[i]),f[a[i]]=i;
ll ans=-1;
for (ll i=1;i<N;i++)
{
if (f[i])
for (ll j=i;j<N;j++)
if (f[j]&&__gcd(i,j)==1)
ans=max(ans,f[i]+f[j]);
}
printf("%lld\n",ans);
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}
E. Scuza(二分+思维)
我们发现到达i点需要的jio长至少为,得到的高度为 ,由于jio长保证单调非减,因此通过预处理得到jio长max的高度,然后通过二分得到答案。
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll n,q;
ll a[Ma];
ll ans[Ma];
void sol()
{
scanf("%lld%lld",&n,&q);
for (ll i=1;i<=n;i++)
scanf("%lld",&a[i]),ans[i]=ans[i-1]+a[i];
for (ll i=1;i<=n;i++)
a[i]=max(a[i],a[i-1]);
while (q--)
{
ll x;
scanf("%lld",&x);
ll l=upper_bound(a+1,a+n+1,x)-a-1;
printf("%lld ",ans[l]);
}
printf("\n");
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}
F. Smaller(贪心)
我们维护s最小与t最大比较即可,复杂度O(26*2*q)
PS:nm没看到初始有a,结果居然能过ps(人麻了)。
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll q;
ll a[Ma];
ll f[26],f2[26];
ll col[26],col2[26];
void ask()
{
for (ll i=0;i<26;i++)
col[i]=f[i],col2[i]=f2[i];
ll l=0,r=25;
while (l<26&&r>=0)
{
while (l<26&&!col[l])
l++;
while (r>=0&&!col2[r])
r--;
if(l==26||r<0)
break;
if (l<r)
{
printf("YES\n");
return;
}
else if (l>r)
{
printf("NO\n");
return;
}
else
{
ll w=min(col[l],col2[r]);
col[l]-=w,col2[r]-=w;
}
}
if (r<0)
printf("NO\n");
else
printf("YES\n");
return;
}
void sol()
{
scanf("%lld",&q);
memset(f,0,sizeof(f));
memset(f2,0,sizeof(f2));
f[0]=f2[0]=1;
ll cnt=0;
while (q--)
{
ll op,x;
string s;
cin>>op>>x>>s;
if (op==1)
{
for (ll i=0;i<s.size();i++)
f[s[i]-'a']+=x;
}
else
{
for (ll i=0;i<s.size();i++)
f2[s[i]-'a']+=x;
}
ask();
}
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}
G. Orray(位运算+贪心)
首先我们发现进行的是or运算,因此我们可以对位进行分类。
假设前i个答案已经确定位ans,那么第i+1个答案应该为max(ans|a[p]),(a[p]未被选取)。
对于我们所选取的数字a[p]。
1.若ans已经覆盖满所有数,即ans=max(ans|a[p]),那么对于所有的p都是等价的(也就是说瞎JB取都可以)
2.否则一定会出现(1<<j)&((ans|a[p])-ans)==1的情况,我们希望j越大越好,而对于(1<<j)的点一定与原答案不相交,即不会重复选(如果重复选则有(1<<j)&ans==1,与上述式子不符),在固定最大j的基础上选择能让ans最大的值并更新ans即可
复杂度为O(n*log(1e9)/30n)
PS2:感觉暴力sort30次也能过(没试过),复杂度在O(30n*logn)
#include <bits/stdc++.h>
#define ll long long
#define ls p<<1
#define rs p<<1|1
#define Ma 1000005
#define N 30
#define mod 1000000007
#define PLL pair<ll,ll>
#define PDD pair<double,double>
using namespace std;
ll n;
ll a[Ma];
ll f[Ma];
vector <ll> v[N];
void sol()
{
for (ll i=0;i<N;i++)
v[i].clear();
scanf("%lld",&n);
for (ll i=1;i<=n;i++)
f[i]=0;
for (ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
for (ll j=0;j<N;j++)
if ((1<<j)&a[i])
v[j].push_back(i);
}
ll ans=0;
for (ll i=N-1;i>=0;i--)
{
if (ans&(1<<i))
continue;
ll ma=0;
for (auto p:v[i]){
if ((ans|a[p])>(ans|a[ma]))
ma=p;
}
if (!ma)
continue;
ans|=a[ma];
f[ma]=1;
printf("%lld ",a[ma]);
}
for (ll i=1;i<=n;i++)
if (!f[i])
printf("%lld ",a[i]);
printf("\n");
return;
}
int main()
{
ll tt;
scanf("%lld",&tt);
while (tt--)
sol();
return 0;
}