Educational Codeforces Round 102 (Rated for Div. 2)

没打,住院了,来补题玩了,EF还没看,估计要鸽。


A. Replacing Elements

水题,维护最小和此小特判即可,或者直接排序找。

B - String LCM

比较裸,先求出最小公倍数长度,然后特判下。

C. No More Inversions

观察下样例就能发现,可以构造一个逆序对和为 1 + 2 + ⋯ + ( n − k ) 1+2+\dots+(n-k) 1+2++(nk)的序列 b b b,因此我们只需先构造一个长度为 n − k + 1 n-k+1 nk+1的连续降序数,放在最后面,然后前面只能按顺序放,因为逆序对不能再增加了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int main(){
	int t;scanf("%d",&t);
	while(t--){
		int n,k;
		scanf("%d%d",&n,&k);
		int c=n-k+1;
		for(int i=1;i<=2*k-n-1;i++) printf("%d ",i);
		for(int i=1;i<=c;i++) printf("%d ",k-i+1);
		printf("\n");
	}
	return 0;
}

D. Program

简单 d p dp dp,一个很显然的想法就是分成三段,去掉给定的 [ l , r ] [l,r] [l,r],只需拼接两段即可,类似维护一个前后缀的最大最小值就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int a[N],pre[N][2],suf[N][2],b[N];
int main(){
	int t;scanf("%d",&t);
	pre[0][0]=pre[0][1]=0;
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		char ch;
		int x=0;
		suf[n+1][0]=1e9,suf[n+1][1]=-1e9;
		for(int i=1;i<=n;i++){
			scanf("\n%c",&ch);
			a[i]=(ch=='+')?1:-1;
			x+=a[i]; 
			b[i]=x;
			pre[i][0]=min(pre[i-1][0],x);
			pre[i][1]=max(pre[i-1][1],x);
		}
		int xx=b[n];
		for(int i=n;i;i--){
			suf[i][0]=min(suf[i+1][0],xx);
			suf[i][1]=max(suf[i+1][1],xx); 
			xx-=a[i];
		}
		while(m--){
			int l,r;
			scanf("%d%d",&l,&r);
			int ml=pre[l-1][0],mr=suf[r+1][0];
			int Ml=pre[l-1][1],Mr=suf[r+1][1];
			int x=min(ml,b[l-1]+mr-((r<n)?b[r]:0));
			int y=max(Ml,b[l-1]+Mr-((r<n)?b[r]:0));
			printf("%d\n",max(1,y-x+1));
		}
	}
	return 0;
}