[BZOJ 5055]膜法師
阿新 • • 發佈:2017-10-03
return log using scan tchar nbsp algo std text
即 ∑ (a_i*a_j*a_k),要求 i<j<k 且 a_i<a_j<a_k
1 2 3 4
對於樣例 1
有滿足條件的序列為
{1,2,3}——6
{1,2,4}——8
{1,3,4}——12
{2,3,4}——24
ans=6+8+12+24=50
數據範圍
30%的數據n<=300
60%的數據n<=3000
100%的數據n<=300000
0<=a[i]<=2147483647
Description
在經歷過1e9次大型戰爭後的宇宙中現在還剩下n個完美維度, 現在來自多元宇宙的膜法師,想偷取其中的三個維度為偉大的長者續秒, 顯然,他能為長者所續的時間,為這三個維度上能量的乘積, 但目前的宇宙很不樂觀,胡亂偷取可能造成維度的崩潰, 所以,他必須按逆序偷取這些維度,且在偷取中, 每次偷取的維度的能量必須嚴格小於他上次偷取的能量, 由於膜法師生活在多元宇宙,所以他可以讓所有可能的偷取方案全部發生 但他數學不好,所以找到了你幫他求出能為長者續幾秒, 你要做的,就是在給定的維度序列a中, 求出所有滿足i<j<k且ai<aj<ak的ai*aj*ak的和Input
第一行1個數 n 第二行n個數 a_iOutput
一個數,表示能為長者續幾秒,由於長者是不朽的, 所以能活很久,不妨將答案對**19260817**取模吧Sample Input1
41 2 3 4
Sample Output1
50Sample Input2
10
6 8 4 1 3 0 7 5 9 2
Sample Output2
1737HINT
樣例解釋有滿足條件的序列為
{1,2,3}——6
{1,2,4}——8
{1,3,4}——12
{2,3,4}——24
ans=6+8+12+24=50
數據範圍
30%的數據n<=300
60%的數據n<=3000
100%的數據n<=300000
0<=a[i]<=2147483647
題解
我們枚舉$j$很顯然答案就是
$$\sum _{j=1} ^n (a[j]*{\sum _{i=1} ^{j-1} a[i]}*{\sum _{k=j+1} ^{n} a[k]})$$
樹狀數組+離散亂搞就可以了。
emmmmmm(惡膜某民命秒沒)~
1 //It is made by Awson on 2017.10.3 2 #include <set> 3 #include <map> 4 #include <cmath> 5 #include <ctime> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <cstdio> 10 #include <string> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 #define LL long long 16 #define Max(a, b) ((a) > (b) ? (a) : (b)) 17 #define Min(a, b) ((a) < (b) ? (a) : (b)) 18 #define sqr(x) ((x)*(x)) 19 #define lowbit(x) ((x)&(-(x))) 20 #define count COUNT 21 using namespace std; 22 const int N = 300000; 23 const LL MOD = 19260817; 24 void read(LL &x) { 25 char ch; bool flag = 0; 26 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == ‘-‘)) || 1); ch = getchar()); 27 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); 28 x *= 1-2*flag; 29 } 30 31 int n; 32 struct tt { 33 LL val; 34 int pos, rank; 35 }a[N+5]; 36 LL sum[N+5], c[N+5], ans; 37 bool comp(const tt &a, const tt &b) { 38 return a.val < b.val; 39 } 40 bool accomp(const tt &a, const tt &b) { 41 return a.pos < b.pos; 42 } 43 44 void add(int x, LL key) { 45 for (; x <= n; x += lowbit(x)) c[x] = (c[x]+key)%MOD; 46 } 47 LL count(int x) { 48 LL cnt = 0; 49 for (; x; x -= lowbit(x)) cnt = (cnt+c[x])%MOD; 50 return cnt; 51 } 52 void work() { 53 scanf("%d", &n); 54 for (int i = 1; i <= n; i++) { 55 read(a[i].val); a[i].pos = i; 56 } 57 sort(a+1, a+n+1, comp); 58 a[1].rank = 1; 59 for (int i = 2; i <= n; i++) 60 a[i].rank = a[i-1].rank+(a[i].val != a[i-1].val); 61 sort(a+1, a+n+1, accomp); 62 for (int i = 1; i <= n; i++) { 63 sum[i] = count(a[i].rank-1); 64 add(a[i].rank, a[i].val); 65 } 66 memset(c, 0, sizeof(c)); 67 LL cnt = 0; 68 for (int i = n; i >= 1; i--) { 69 LL tmp = count(a[i].rank); 70 tmp = (cnt+MOD-tmp)%MOD; 71 ans = (ans+sum[i]*tmp%MOD*a[i].val)%MOD; 72 add(a[i].rank, a[i].val); 73 cnt = (cnt+a[i].val)%MOD; 74 } 75 printf("%lld\n", ans); 76 } 77 int main() { 78 work(); 79 return 0; 80 }
[BZOJ 5055]膜法師