Solution : P10173(maxiMINImax)
Argon_Cube · · 题解
首先看到三个区间肯定是枚举中间那个,然后看到
其次我们发现三个区间不交的条件是没用的,也就是说只要有两个区间有交集那么这种方案一定贡献为
现在我们只需要保证
#include <algorithm>
#include <iostream>
#include <vector>
#include <bitset>
#include <string>
#include <stack>
#include <array>
using namespace std;
stack<int,vector<int>> mnstk;
array<int,1000002> vals,ivals,bidt1,bidt2,bidt3,bidt4,rgln,rgrn,rglx,rgrx;
const int moder=9712176;
inline void update(int idx,long long val,int cnt,decltype(bidt1)& bidt)
{
while(idx<=cnt)
bidt[idx]=(bidt[idx]+val)%moder,idx+=-idx&idx;
}
inline int query(int idx,decltype(bidt1)& bidt)
{
int result=0;
while(idx)
result=(result+bidt[idx])%moder,idx-=idx&-idx;
return result;
}
int main(int argc,char* argv[],char* envp[])
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int cnt;
cin>>cnt;
for(int i=1;i<=cnt;i++)
cin>>vals[i],ivals[vals[i]]=i;
vals[0]=vals[cnt+1]=0;
mnstk.push(0);
for(int i=1;i<=cnt+1;i++)
{
while(vals[mnstk.top()]>vals[i])
rgrn[mnstk.top()]=i,mnstk.pop();
rgln[i]=mnstk.top();
mnstk.push(i);
}
mnstk.pop();
vals[0]=vals[cnt+1]=cnt+1;
for(int i=1;i<=cnt+1;i++)
{
while(vals[mnstk.top()]<vals[i])
rgrx[mnstk.top()]=i,mnstk.pop();
rglx[i]=mnstk.top();
mnstk.push(i);
}
int answer=0;
for(int idx=1;idx<=cnt;idx++)
{
long long i=ivals[idx];
long long cntn=(rgrn[i]-i+0ll)*(i-rgln[i])%moder,cntx=(rgrx[i]-i+0ll)*(i-rglx[i])%moder;
long long a=query(i,bidt1),b=query(cnt-i+1,bidt2),c=query(i,bidt3),d=query(cnt-i+1,bidt4);
answer=(answer+cntn*((c*d-idx*((a*d+b*c)%moder)%moder+moder+a*b%moder*idx%moder*idx)%moder))%moder;
// cerr<<idx<<' '<<i<<' '<<cntn<<' '<<cntx<<' '<<answer<<'\n';
update(i,cntx,cnt,bidt1),update(cnt-i+1,cntx,cnt,bidt2),update(i,cntx*idx,cnt,bidt3),update(cnt-i+1,cntx*idx,cnt,bidt4);
}
cout<<answer;
return 0;
}