【JZOJ5231】【NOIP2017模拟A组模拟8.5】序列问题
2017-08-09 09:44
501 查看
Description
Data Constraint
对于30%的数据,n<=5000对于60%的数据,n<=50000
对于100%的数据,n<=500000,0<=A[i]<=10^9
Solution
这道题有很多种解法,我这里主要讲讲分治和线段树两种解法。分治:我们对于每一次二分出来的mid,我们考虑4种情况:最大值最小值在同一边且跨过mid(左右),最大值最小值不在同一边且跨过mid(左右)。
我们设mx[i]表示mid到i的最大值。mi[i]同理。
对于最大值最小值在同一边且跨过mid的情况:我们可以枚举一边,另一边用一个指针单调移动,强制要求maxi>maxj&&mini
Code
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const int maxn=5e5+5,mo=1e9+7; ll a[maxn],d[maxn],mx[maxn],mi[maxn],sum[maxn]; ll n,i,t,j,k,x,y,z,num,ans; void dg(int l,int r){ if (l==r){ ans=(ans+a[l]*a[l]%mo)%mo;return; } if (l>r) return;int mid=(l+r)/2; mi[mid+1]=mx[mid+1]=a[mid+1];mi[mid]=mx[mid]=a[mid]; for (i=mid+2;i<=r;i++) mi[i]=min(mi[i-1],a[i]),mx[i]=max(mx[i-1],a[i]); for (i=mid-1;i>=l;i--) mi[i]=min(mi[i+1],a[i]),mx[i]=max(mx[i+1],a[i]); sum[l-1]=0; for (i=l;i<=mid;i++) sum[i]=sum[i-1]+mi[i]; j=mid; for (i=mid+1;i<=r;i++){ while (mi[j]>=mi[i] && mx[j]<=mx[i] && j>=l) j--; ans=(ans+mx[i]*mi[i]%mo*(mid-j)%mo)%mo; } j=mid+1; for (i=mid;i>=l;i--){ while (mi[j]>=mi[i] && mx[j]<=mx[i] && !(mi[j]==mi[i] && mx[j]==mx[i])&& j<=r) j++; ans=(ans+mx[i]*mi[i]%mo*(j-mid-1)%mo)%mo; } j=mid;k=mid; for (i=mid+1;i<=r;i++){ while (mx[j]<mx[i] && j>=l)j--; while (mi[k]>=mi[i] && k>=l) k--; if (j+1<=k)ans=(ans+(sum[k]-sum[j])%mo*mx[i]%mo)%mo; } j=mid;k=mid; for (i=l;i<=mid;i++) sum[i]=sum[i-1]+mx[i]; for (i=mid+1;i<=r;i++){ while (mx[j]<=mx[i] && j>=l)j--; while (mi[k]>mi[i] && k>=l) k--; if (k+1<=j)ans=(ans+(sum[j]-sum[k])%mo*mi[i]%mo)%mo; } dg(l,mid);dg(mid+1,r); } int main(){ freopen("seq.in","r",stdin);freopen("seq.out","w",stdout); scanf("%lld",&n); for (i=1;i<=n;i++) scanf("%lld",&a[i]); dg(1,n); printf("%lld\n",ans); }
相关文章推荐
- 【jzoj5231】【NOIP2017模拟A组模拟8.5】【序列问题】 【分治】
- JZOJ.5231【NOIP2017模拟8.5】序列问题
- jzoj5249 【NOIP2017提高A组模拟8.10】文本编辑器 (序列修改类问题,数据结构)
- JZOJ5230. 【NOIP2017模拟A组模拟8.5】队伍统计
- JZOJ 5371. 【NOIP2017提高A组模拟9.17】组合数问题
- 【jzoj5232】【NOIP2017模拟A组模拟8.5】【带权排序】【线段树】
- [jzoj]3889. 【NOIP2014模拟10.25B组】序列问题(DP的各种方法+细节+详细分析)
- JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计
- 【JZOJ5232】【NOIP2017模拟A组模拟8.5】带权排序
- jzoj. 3889. 【NOIP2014模拟10.25B组】序列问题
- [jzoj3889]【NOIP2014模拟10.25B组】序列问题
- JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计
- 【jzoj5340】【NOIP2017模拟9.2A组】【春思】
- 【JZOJ 4931】【NOIP2017提高组模拟12.24】A
- JZOJ 5385. 【NOIP2017提高A组模拟9.23】Carry
- 【JZOJ 4931】【NOIP2017提高组模拟12.24】A
- 【JZOJ 5405】【NOIP2017提高A组模拟10.10】Permutation
- JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
- JZOJ5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
- 【jzoj5286】【NOIP2017提高A组模拟8.16】【花花的森林 】【时间倒流】