Uoj_ 213 [UNR_ 1] Grail Monotone Stack + Difference

Description

For a sequence of length n, the weights of an interval are defined as the maximum in the interval. The sum of weights of all intervals with length I denoted by ans[i] is 998244353
Questioning the XOR and Sum of ans
n≤1e6n\le1e6n≤1e6

Solution

Consider finding the interval [L[i],R[i], where element I is the maximum value. Note that the shorter interval is mn and the longer interval is mx. Let's talk about the contribution to this position in each length interval.
When x<=mn, the interval must contain at least the position i, then ans[x] must add x*a[i]
When Mn < x<= mx, it is not difficult to find that the coefficients are exactly mn.
When mx<x<=mx+mn-1, the coefficient is mx+mn-x.
It can be found that 1 and 3 are functions of the first order and 2 are constants. We can maintain this by second-order difference, and of course we can also maintain the coefficients and constants separately for one time, and multiply them by their respective x.

Code

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)

typedef long long LL;
const int MOD=998244353;
const int N=2000005;

LL a[N],L[N],R[N],st[N],s[N],t[N],top;

int read() {
	int x=0,v=1; char ch=getchar();
	for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):v,ch=getchar());
	for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
	return x*v;
}

void upd(LL &x,LL v) {
	x=((x+v)%MOD+MOD)%MOD;
}

int main(void) {
	freopen("data.in","r",stdin);
	int n=read();
	rep(i,1,n) a[i]=read();
	st[top=1]=L[1]=1;
	rep(i,2,n) {
		while (top&&a[i]>a[st[top]]) top--;
		st[++top]=i; L[i]=st[top-1]+1;
	}
	st[top=0]=n+1;
	st[top=1]=n,R[n]=n;
	drp(i,n-1,1) {
		while (top&&a[i]>=a[st[top]]) top--;
		st[++top]=i; R[i]=st[top-1]-1;
	}
	rep(i,1,n) {
		LL l=i-L[i]+1,r=R[i]-i+1;
		LL mn=std:: min(l,r),mx=r+l-mn;
		upd(s[1],a[i]),upd(s[mn+1],MOD-a[i]);
		upd(s[mx+1],MOD-a[i]),upd(s[mx+mn],a[i]);
		upd(t[mn+1],mn*a[i]%MOD),upd(t[mx+1],MOD-mn*a[i]%MOD);
		upd(t[mx+1],(mx+mn)%MOD*a[i]%MOD),upd(t[mx+mn],MOD-(mx+mn)%MOD*a[i]%MOD);
	}
	rep(i,1,n) upd(s[i],s[i-1]);
	rep(i,1,n) upd(t[i],t[i-1]);
	rep(i,1,n) upd(t[i],s[i]*i%MOD);
	LL ans=0;
	rep(i,1,n) ans=ans^t[i];
	printf("%lld\n", ans);
	return 0;
}

Posted by golden_water on Tue, 16 Apr 2019 13:42:32 -0700