延安OJ 2022/10/23 讲评
T1 黑键
50分代码 //没处理好细节
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll ans,t=0;
string str;
int main(){
cin>>str;
for(int i=1;i<=str.size();i++){
if(str[i]=='W'){
ans+=i-t;
t++;
}
}
cout<<ans;
return 0;
}
满分代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll ans,n;
char ch[10000005];
int main(){
scanf("%s",ch+1),n=strlen(ch+1);
for(register int i=1,tot=0;i<=n;i++){
if(ch[i]^'B') tot++,ans+=i-tot;
}
cout<<ans;
return 0;
}
T2
T3
T4
满分代码
#include<bits/stdc++.h>
#define re register
#define ull unsigned long long
#define ll long long
using namespace std;
ll n,m,a[200005];
int main(){
cin>>n;
for(re int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(re int i=1<<30,l,r;i;i>>=1){
l=1,r=n;
for(;l<r;){
if(a[l]==-1 || ~a[r]&&a[l]+a[r]<i) l++;
else if(a[r]==-1 || a[l]+a[r]>i) r--;
else ans++,a[l]=a[r]=-1;
}
}
cout<<ans;
return 0;
}
T5
T6
-
讲解
T1.
求一个 01 序列的逆序对个数。
(i,j) a_j=1
mathcal{O(n)}
T2.
当 y=max{a,b} 时,f(...,max{a,b}) = 1。
直接从 last=1, k=max{a,b} 开始算即可。
T3.
选 m 个:
- 宽度:∑
- 高度:max
二维偏序:O(n^2) -> O(n log n)
枚举高度 h,最小宽度是多少。
用堆维护第二维即可。
T4.
一个结论:从大到小地匹配每个元素更优。
从大到小枚举每一个数,贪心地匹配这个数,找到与其对应匹配的数。
O(log^2n)。
枚举 2^k 的 k ∈ [1,31]。
用双指针 O(n) 判定。
复杂度 O(30n)。
T5.
前置知识:序列 Hash。
哈希 √
序列 a 看做 b 进制的数,并且 mod p。
b,p 均为质数 b=23,p=131 出错概率极小,可以忽略不计。
排列一个性质:值域连续。
a+x ,唯一匹配 b 的子序列。
a 序列 变成 a+x 时,直接维护 hash 值。
令 b[pos_i]=i,线段树维护 pos_i 的 hash 值。
a+x 在 log n 时间内比较序列。
枚举 x,n log n。

浙公网安备 33010602011771号