延安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 个:

  1. 宽度:∑
  2. 高度: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。

posted @ 2022-10-23 19:25  織田信長  阅读(51)  评论(0)    收藏  举报
Title