zoukankan      html  css  js  c++  java
  • ARC115ELEQ and NEQ【容斥,dp,线段树】

    正题

    题目链接:https://atcoder.jp/contests/arc115/tasks/arc115_d


    题目大意

    \(n\)个数字的序列\(x\),第\(x_i\in [1,A_i]\cap Z\)。要求相邻的不同,求方案数。

    \(1\leq n\leq 5\times 10^5,1\leq A_i\leq 10^9\)


    解题思路

    考虑容斥,如果有\(k\)个相邻的相等那么容斥系数就是\((-1)^k\)。那我们把\(n\)分为若干个连续的相同段,然后每一段的容斥系数分开算就好了,这样就是一个可以\(dp\)的式子了。

    \(f_i\)表示以\(i\)结尾的段时的值,那么有转移方程

    \[f_i=\sum_{j=0}^{i-1}f_j\times min\{A_k\}(k\in(j,i])\times (-1)^{i-j-1} \]

    这个\(min\{A_k\}\)每次加入一个新的时候会影响一个后缀,用单调栈找到这个后缀,然后把\(f_i\)丢进线段树里。

    而那个容斥系数就是每次整个线段树乘上一个\((-1)\),这个丢到外面处理就好了。

    时间复杂度\(O(n\log n)\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=5e5+10,M=N<<2,P=998244353;
    ll n,a[N],q[N],f[N];
    ll w[M],lazy[M],v[M];
    void Downdata(ll x){
    	if(!lazy[x])return;
    	w[x*2]=v[x*2]*lazy[x]%P;
    	w[x*2+1]=v[x*2+1]*lazy[x]%P;
    	lazy[x*2]=lazy[x*2+1]=lazy[x];
    	return;
    }
    void Change(ll x,ll L,ll R,ll l,ll r,ll c){
    	if(L==l&&R==r){lazy[x]=c;w[x]=v[x]*c%P;return;}
    	ll mid=(L+R)>>1;Downdata(x);
    	if(r<=mid)Change(x*2,L,mid,l,r,c);
    	else if(l>mid)Change(x*2+1,mid+1,R,l,r,c);
    	else Change(x*2,L,mid,l,mid,c),Change(x*2+1,mid+1,R,mid+1,r,c);
    	w[x]=(w[x*2]+w[x*2+1])%P;v[x]=(v[x*2]+v[x*2+1])%P;return; 
    }
    void Insert(ll x,ll L,ll R,ll pos,ll c){
    	if(L==R){v[x]=c;w[x]=c*lazy[x]%P;return;}
    	ll mid=(L+R)>>1;Downdata(x);
    	if(pos<=mid)Insert(x*2,L,mid,pos,c);
    	else Insert(x*2+1,mid+1,R,pos,c);
    	w[x]=(w[x*2]+w[x*2+1])%P;v[x]=(v[x*2]+v[x*2+1])%P;return;
    }
    signed main()
    {
    	scanf("%lld",&n);
    	ll top=1;Insert(1,1,n,1,P-1);
    	for(ll i=1;i<=n;i++){
    		scanf("%lld",&a[i]);
    		while(top>0&&a[i]<a[q[top]])top--;
    		Change(1,1,n,q[top]+1,i,a[i]);q[++top]=i;
    		f[i]=(i&1)?(P-w[1]):w[1];
    		if(i!=n)Insert(1,1,n,i+1,P-w[1]);
    	}
    	printf("%lld\n",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    发明专利授权容易吗?
    No module named 'PyQt5.QtWebEngineWidgets' 解决方法
    Python可视化界面编程入门
    Python用户界面编程PyQt5的四种的布局方式
    cmd进入任何一个文件夹的步骤?
    cmd如何进入和退出Python编程环境?
    《C++ Primer Plus》16.3 标准模板库 学习笔记
    《C++ Primer Plus》16.2 智能指针模板类
    《C++ Primer Plus》16.1 string类 学习笔记
    Python错误和异常 学习笔记
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14578706.html
Copyright © 2011-2022 走看看