ABC471
发挥最好的一集,直接干掉 ABCDE

A
送分题,注意判断整除
https://atcoder.jp/contests/abc471/submissions/78380679
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=-1;
int a,b;
bool solve()
{
if(a+b==9) return 1;
if(a-b==9) return 1;
if(a*b==9) return 1;
if(a%b==0&&a/b==9) return 1;
return 0;
}
int main()
{
// freopen("neuvillette.in","r",stdin);
// freopen("neuvillette.out","w",stdout);
cin>>a>>b;
cout<<(solve()?"Nine":"Nein")<<'\n';
return 0;
}
/*
- 标题 『A - Nine or Nein』
- 链接 『https://atcoder.jp/contests/abc471/tasks/abc471_a』
- 时限 『2000 ms』
- 用时 『h min』
- 思路:
*/
B
送分题
https://atcoder.jp/contests/abc471/submissions/78386370
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=-1;
int n;
string s;
map<string,int> cnt;
int main()
{
// freopen("neuvillette.in","r",stdin);
// freopen("neuvillette.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s;
for(auto &c:s) c=tolower(c);
cnt[s]++;
}
int mx=0;
for(auto [k,v]:cnt) mx=max(mx,v);
cout<<mx<<'\n';
return 0;
}
/*
- 标题 『B - Survey Tabulation』
- 链接 『https://atcoder.jp/contests/abc471/tasks/abc471_b』
- 时限 『2000 ms』
- 用时 『h min』
- 思路:
*/
C
直接模拟即可。
https://atcoder.jp/contests/abc471/submissions/78400423
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=3e5+7;
int n;
ll a[N];
ll dis(int x,int y)
{
if(x<=0||y<=0||x>n||y>n) return 1e18;
return abs(a[x]-a[y]);
}
int main()
{
// freopen("neuvillette.in","r",stdin);
// freopen("neuvillette.out","w",stdout);
cin>>n; n++;
for(int i=1;i<n;i++) cin>>a[i]; a[n]=0;
sort(a+1,a+n+1);
ll ans=0;
int l=lower_bound(a+1,a+n+1,0)-a;
int r=l; //[l,r]为走完的区间的下标
int cur=l;
for(int i=1;i<n;i++)
{
int r1=r+1;
int l1=l-1;
int cur1;
// cerr<<cur<<' '<<l1<<' '<<r1<<'\n';
if(dis(cur,r1)<dis(cur,l1)) cur1=r1,r=r1;
else cur1=l1,l=l1;
// cerr<<cur<<' '<<cur1<<'\n';
ans+=abs(a[cur]-a[cur1]);
cur=cur1;
}
cout<<ans;
return 0;
}
/*
- 标题 『C - Cookies and Greedy Takahashi』
- 链接 『https://atcoder.jp/contests/abc471/tasks/abc471_c』
- 时限 『2000 ms』
- 用时 『h min』
- 思路:
lower_bound,upper_bound?似乎不用
*/
D
经典 Trick 题。
首先每个单位时刻电量增加 \(1\),假如某个元素在 \(t_0=0\) 就被加入,那么它在 \(t_1\) 时刻的电量就是 \(t_1\)。
如果元素不在 \(t_0=0\) 时加入呢?假设电池在时刻 \(t\) 被接入,初始电量为 \(w\)。那么到了未来任意一个查询时刻 \(T\),这块电池的理论电量(未达上限前)应该是:
注意,在同一个查询时刻 \(T\) 下,优先队列里所有电池所加的 \(T\) 是完全一样的公共常数。因此,我们不需要实时维护这个不断增长的 \(T\),只需要比较每块电池的 \(w - t\) 就行了。所以,我们在插入时直接把 \(w - t\) 作为键值压入优先队列就好了。这里用到了一点前缀和的思想。
等到查询取堆顶时,我们再利用当前的真实时刻 \(t_q\) 还原出理论电量:\((w - t) + t_q\)。最后别忘了,由于电池存在最大容量 \(V\),所以最终输出的实际电量应为 \(\min((w - t) + t_q,\ V)\)。
https://atcoder.jp/contests/abc471/submissions/78407551
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=-1;
ll q,v;
priority_queue<ll> pq;
int main()
{
// freopen("neuvillette.in","r",stdin);
// freopen("neuvillette.out","w",stdout);
cin>>q>>v;
int op; ll t,w;
while(q--)
{
cin>>op>>t;
if(op==1)
{
cin>>w;
pq.push(w-t);
}
else
{
if(pq.empty()) cout<<"-1\n";
else
{
auto u=pq.top(); pq.pop();
if(u+t>=v) cout<<v<<'\n';
else cout<<u+t<<'\n';
}
}
}
return 0;
}
/*
- 标题 『D - Chargers』
- 链接 『https://atcoder.jp/contests/abc471/tasks/abc471_d』
- 时限 『2000 ms』
- 用时 『h min』
- 思路:
考虑记录一个从开始到现在的计时器,放进去时先减掉这个值,然后取出来的时候加回去?这是一个经典套路
我去怎么现在做atcoder这么顺啊?这就是集训的成果吗
*/
E
感觉这个 Trick 非常像联合权值。
题目要求
首先考虑到一个式子:
考虑全部 \(\binom nk\) 种情况:
- 每一个 \(a_i^2\) 出现的次数为 \(\binom{n-1}{k-1}\),因为相当于在 \((a_1+a_2+\cdots+a_i)^2\) 这个括号中固定了 \(a_i\),剩下还需要从 \(n-1\) 个元素中选择 \(k-1\) 个元素;
- 每一个 \(a_i a_j\) 出现的次数为 \(\binom{n-2}{k-2}\),因为相当于在 \((a_1+a_2+\cdots+a_i+a_j)\) 这个括号中固定了 \(a_i\) 和 \(a_j\),剩下还需要从 \(n-2\) 个元素中选择 \(k-2\) 个元素。
所以就可以注意到以下式子:
红色部分显然直接计算,蓝色部分使用一个前缀和即可。
第一次场切 E,纪念一下(
https://atcoder.jp/contests/abc471/submissions/78430309
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=2e5+17;
constexpr int mod=998244353;
int n,k;
ll a[N],f[N],s[N],invf[N];
ll ksm(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll getsum(int l,int r)
{
return (s[r]+mod-s[l-1])%mod;
}
ll C(int n0,int k0)
{
if(n0<k0) return 0;
return f[n0]*invf[k0]%mod*invf[n0-k0]%mod;
}
int main()
{
// freopen("neuvillette.in","r",stdin);
// freopen("neuvillette.out","w",stdout);
cin>>n>>k;
f[0]=invf[0]=1;
for(int i=1;i<=n+5;i++) f[i]=(f[i-1]*i)%mod;
for(int i=1;i<=n+5;i++) invf[i]=ksm(f[i],mod-2);
// cerr<<C(1,0)<<'\n';
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) s[i]=(s[i-1]+a[i])%mod;
ll ans=0;
for(int i=1;i<=n;i++) ans=(ans+a[i]*a[i]%mod*C(n-1,k-1)%mod)%mod;
// cerr<<ans<<'\n';
for(int i=1;i<n;i++)
{
ans=(ans+2*C(n-2,k-2)*getsum(i+1,n)%mod*a[i]%mod)%mod;
// cerr<<i<<' '<<getsum(i+1,n)<<'\n';
}
cout<<ans%mod;
return 0;
}
/*
- 标题 『E - Sum of Square of Sum』
- 链接 『https://atcoder.jp/contests/abc471/tasks/abc471_e』
- 时限 『2000 ms』
- 用时 『h min』
- 思路:
考虑(a[1]+a[2]+...+a[n])^2=a[1]^2+a[2]^2+...+a[n]^2 + 2a[1]a[2]+2a[1]a[3]+...+2a[n-1]a[n]
对于每一种组合:
前面那一大坨的平方,a[i]^2出现次数一共有C(n-1,k-1)
后面2a[i]a[j],一共有C(k,2)项,显然直接暴力O(k^2)不可能,所以考虑拆
注意到
\sum_{|T|=k} \left(\sum_{i\in T} a_i\right)^2 = \binom{n-1}{k-1}\sum_{i=1}^n a_i^2 + 2\binom{n-2}{k-2}\sum_{1\le i<j\le n} a_i a_j
要求这个东西\sum_{1\le i<j\le n} a_i a_j
我操这不是直接前缀和吗???
*/

浙公网安备 33010602011771号