1. 程式人生 > >bzoj5055

bzoj5055

urn log gin center scrip sort push 樹狀數組 div

膜法師

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 112 Solved: 59
[Submit][Status][Discuss]

Description

在經歷過1e9次大型戰爭後的宇宙中現在還剩下n個完美維度, 現在來自多元宇宙的膜法師,想偷取其中的三個維度為偉大的長者續秒, 顯然,他能為長者所續的時間,為這三個維度上能量的乘積, 但目前的宇宙很不樂觀,胡亂偷取可能造成維度的崩潰, 所以,他必須按逆序偷取這些維度,且在偷取中, 每次偷取的維度的能量必須嚴格小於他上次偷取的能量, 由於膜法師生活在多元宇宙,所以他可以讓所有可能的偷取方案全部發生 題目描述 但他數學不好,所以找到了你幫他求出能為長者續幾秒, 你要做的,就是在給定的維度序列a中, 求出所有滿足i<j<k且ai<aj<ak的ai*aj*ak的和 即 ∑ (a_i*a_j*a_k),要求 i<j<k 且 a_i<a_j<a_k

Input

第一行1個數 n 第二行n個數 a_i

Output

一個數,表示能為長者續幾秒,由於長者是不朽的, 所以能活很久,不妨將答案對**19260817**取模吧

Sample Input

樣例1
4
1 2 3 4

樣例二
10
6 8 4 1 3 0 7 5 9 2
很簡單預處理+樹狀數組即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using
namespace std; #define lowbit(x) x&(-x) #define maxn 300010 #define pp 19260817 #define ll long long ll tree[maxn],tree2[maxn],a[maxn],n; long long ans; vector<ll> b; void update(ll u,ll c) { for(ll i=u;i<=n;tree[i]+=c,tree[i]%=pp,i+=lowbit(i)); } void update2(ll u,ll c) {
for(ll i=u;i<=n;tree2[i]+=c,tree2[i]%=pp,i+=lowbit(i)); } ll query(ll u) { ll sum=0; for(ll i=u;i>0;sum+=tree[i],sum%=pp,i-=lowbit(i)); return sum; } ll query2(ll u) { ll sum=0; for(ll i=u;i>0;sum+=tree2[i],sum%=pp,i-=lowbit(i)); return sum; } int main() { scanf("%lld",&n); for(ll i=1;i<=n;i++) { scanf("%lld",&a[i]); a[i]%=pp; b.push_back(a[i]); } sort(b.begin(),b.end()); b.erase(unique(b.begin(),b.end()),b.end()); for(ll i=1;i<=n;i++) a[i]=lower_bound(b.begin(),b.end(),a[i])-b.begin()+1; update(a[1],b[a[1]-1]); update(a[2],b[a[2]-1]); if(a[1]<a[2]) update2(a[2],b[a[1]-1]*b[a[2]-1]%pp); for(ll i=3;i<=n;i++) { ans+=b[a[i]-1]*query2(a[i]-1); ans%=pp; update(a[i],b[a[i]-1]%pp); update2(a[i],query(a[i]-1)*b[a[i]-1]%pp); } printf("%lld\n",ans); }

bzoj5055