CF1517E - Group Photo

CF1517E - Group Photo

题目大意

对于一个长度为\(n\)的序列,每个元素有一个权值\(a_i\),现在为这个序列染色,每个不是C就是P,且满足

\(c_i-c_{i-1}\leq c_{i+1}-c_i\)

\(p_i-p_{i-1}\ge p_{i+1}-p_i\)

\[\ \]

模型分析

由一个Simple的性质

对于\(c\)构成的连续段,只有第一段长度可能>1

对于\(p\)构成的连续段,只有最后一段长度可能>1

综合以上容易发现

中间交错段都是一个c一个p,两端可以有一段极长的

比较general的情况可以表示如下

# 1 2 3 4 5 6 7 8 9 10 11
C - - - - - (-)
P (-) - - - -

比较丑哈

side 就是P在C前面且只有一个长段

那么枚举\(P\)的长段开头,二分/尺取前面交错部分长度即可

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair <int,int> Pii;
#define reg register
#define mp make_pair
#define pb push_back
#define Mod1(x) ((x>=P)&&(x-=P))
#define Mod2(x) ((x<0)&&(x+=P))
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }

char IO;
template <class T=int> T rd(){
	T s=0; int f=0;
	while(!isdigit(IO=getchar())) f|=IO=='-';
	do s=(s<<1)+(s<<3)+(IO^'0');
	while(isdigit(IO=getchar()));
	return f?-s:s;
}

const int N=2e5+10,P=998244353;

int n,a[N];
ll s[N],t[N];

int Calc(int i,ll d){
	int ans=0;
	int res=-1;
	for(int l=0,r=(i-1)/2,mid;l<=r;) 
		if(mid=(l+r)>>1,d-t[i]+t[i-mid*2]-s[i-mid*2]>0) r=mid-1,res=mid;
		else l=mid+1;
	if(~res) ans+=(i-1)/2-res+1;
	if(i==1) return ans;
	res=-1;
	for(int l=0,r=(i-2)/2,mid;l<=r;) 
		if(mid=(l+r)>>1,d-t[i]+t[i-mid*2]-s[i-mid*2]+2*a[1]>0) r=mid-1,res=mid;
		else l=mid+1;
	if(~res) ans+=(i-2)/2-res+1;
	return ans;
}

int main(){
	rep(_,1,rd()) {
		n=rd();
		rep(i,1,n) a[i]=rd();
		rep(i,1,n) s[i]=s[i-1]+a[i];
		rep(i,1,n) t[i]=a[i]-t[i-1];
		ll ans=0;
		rep(i,1,n-1) {
			ans+=Calc(i,s[n]-s[i]);
			if(i<n-1) ans+=Calc(i,s[n-1]-s[i]-a[n]);
		}
		rep(i,1,n) if(s[i]-(s[n]-s[i])>0) ans++;
		printf("%lld\n",ans%P);
	}
}

posted @ 2021-05-05 16:39  chasedeath  阅读(118)  评论(0编辑  收藏  举报