zoukankan      html  css  js  c++  java
  • CF1517E

    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
    ",ans%P);
    	}
    }
    
    
  • 相关阅读:
    阅读随笔
    四则运算生成器基础版
    《梦断代码》阅读计划
    JavaScript值传递和引用传递
    nodejs包高效升级插件npm-check-updates
    JavaScript常用技巧之进制转换
    js 数组、字符串、Json互相转换
    利用Stream模式进行文件拷贝
    ACM-ICPC 2018 焦作赛区网络预赛 H、L
    ACM-ICPC 2018 沈阳赛区网络预赛 G 容斥原理
  • 原文地址:https://www.cnblogs.com/chasedeath/p/14732033.html
Copyright © 2011-2022 走看看