Educational Codeforces Round 65 选做

好久没更博客了,随便水一篇

E. Range Deleting

题意

给你一个长度为 (n) 的序列 (a_1,a_2,dots a_n) ,定义 (f(l,r)) 为删除 (lle a_ile r) 元素后的序列。求所有 (f(l,r)) 单调不降序列的数量。

(n,a_ile 10^6)

题解

简单题,但还是调了一年(见代码注释)。

考虑删除后的区间,一定是一段前缀并上一段后缀。首先找到一段合法的极长后缀,然后枚举前缀,在保证前缀合法的情况下双指针统计有多少个合法的后缀即可。复杂度 (O(n))

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c=getchar(); int x=0;
	for(;c<'0'||c>'9';c=getchar());
	for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
	return x;
}
const int N=1e6+5;
int a[N],n,x,ans,fst[N],lst[N],gst[N];
int main()
{
	#ifdef lc
		freopen("in.txt","r",stdin);
	#endif
	n=gi(),x=gi();
	memset(fst,0x3f,sizeof(fst));
	for(int i=1;i<=n;++i)
	{
		a[i]=gi();
		if(fst[a[i]]==fst[0]) fst[a[i]]=i;
		lst[a[i]]=i;
	}
	int r=x,f=fst[x]; gst[x]=fst[x];
	for(;r>=1;--r)
	{
		if(gst[r]<lst[r-1]) break;
		gst[r-1]=min(gst[r],fst[r-1]);
	}
	if(!r)
	{
		printf("%I64d",1ll*x*(x+1)/2);
		return 0;
	}
	int l=0;
	long long ans=0;
	for(int i=1;i<=x;++i)
	{
		for(r=max(r,i);r<=x&&gst[r]<l;++r);
		ans+=x-r+2; //注意不能 --r, ans+=x-r+1 ……
		if(fst[i]<l) break;
		l=max(l,lst[i]);
	}
	printf("%I64d",ans);
}

F. Scalar Queries

题意

给你一个长度为 (n) 的序列 (a_1,a_2,dots a_n) ,设 (f(l,r)) 等于序列 ([l,r]) 内每个数乘上在当前区间的排名的和。求 (sum_{1le lle rle n} f(l,r)) .

(nle 5cdot 10^5, a_ile 10^9)

题解

比前一题还简单,直接考虑当前数的贡献。离散化后直接两个树状数组维护左边和右边比当前数小的数的个数和下标和,随便统计一下就好。(O(nlog n))

代码略丑。

code

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=5e5+5,Mod=1e9+7;
int a[N],b[N],n,t1[N],t2[N],s1[N],s2[N],c[N],m,ans;
#define lowbit(x) (x&-x)
void upd(int* t, int i, int w) {
	for(;i<=m;i+=lowbit(i)) t[i]=((t[i]+w)%Mod+Mod)%Mod;
}
int qry(int* t, int i)
{
	int r=0;
	for(;i;i-=lowbit(i)) r=(r+t[i])%Mod;
	return r;
}
void add(int x) { ans=(ans+x)%Mod; }
int mul(int x, int y) {
	x=1ll*(x+Mod)%Mod, y=1ll*(y+Mod)%Mod;
	return 1ll*x*y%Mod;
}
int main()
{
	#ifdef lc
		freopen("in.txt","r",stdin);
	#endif
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]), c[i]=a[i];
	sort(c+1,c+1+n),m=unique(c+1,c+1+n)-c-1;
	for(int i=1;i<=n;++i)
	{
		b[i]=lower_bound(c+1,c+1+m,a[i])-c;
		upd(t2,b[i],1);
		upd(s2,b[i],i);
	}
	for(int i=1;i<=n;++i)
	{
		int x1=qry(t1,b[i]),y1=qry(s1,b[i]),x2=qry(t2,b[i]),y2=qry(s2,b[i]);
		add(mul(a[i],mul(i,((mul(n+1,x2)-y2)%Mod+Mod)%Mod)));
		add(mul(a[i],mul(n-i+1,y1)));
		upd(t2,b[i],-1),upd(s2,b[i],-i);
		upd(t1,b[i],1),upd(s1,b[i],i);
	}
	printf("%d",ans);
}

原文地址:https://www.cnblogs.com/farway17/p/10948189.html