1. 程式人生 > >BZOJ5055: 膜法師

BZOJ5055: 膜法師

sed ide pri space 方法 int cnblogs ons pre

n<=300000個數求所有i<j<k,Ai>Aj>Ak的Ai*Aj*Ak的和。

還以為什麽奇怪題呢。。就是個偏序。。

i<j,Ai>Aj就是逆序對模板,把樹狀數組裏的+1改成+Ai即可,每個數的Ai*Aj數就樹狀數組求個前綴和即可。

上面那個算出來存在Bi,再用類似的方法求一次即可。

技術分享
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 //#include<queue>
 6
//#include<iostream> 7 using namespace std; 8 9 int n; 10 #define maxn 300011 11 const int mod=19260817; 12 int a[maxn],id[maxn],two[maxn],thr[maxn]; 13 int lisan[maxn]; 14 struct BIT 15 { 16 int a[maxn]; 17 void clear() {memset(a,0,sizeof(a));} 18 void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]=(a[x]+v)%mod;}
19 int query(int x) {int ans=0;for (;x;x-=x&-x) ans=(ans+a[x])%mod;return ans;} 20 }t; 21 int main() 22 { 23 scanf("%d",&n); 24 for (int i=1;i<=n;i++) scanf("%d",&a[i]),lisan[i]=a[i]; 25 sort(lisan+1,lisan+1+n); 26 for (int i=1;i<=n;i++) id[i]=lower_bound(lisan+1,lisan+1
+n,a[i])-lisan; 27 t.clear(); 28 for (int i=1;i<=n;i++) 29 { 30 t.add(id[i],a[i]); 31 two[i]=1ll*a[i]*t.query(id[i]-1)%mod; 32 } 33 t.clear(); 34 int ans=0; 35 for (int i=1;i<=n;i++) 36 { 37 t.add(id[i],two[i]); 38 ans=(ans+1ll*a[i]*t.query(id[i]-1)%mod)%mod; 39 } 40 printf("%d\n",ans); 41 return 0; 42 }
View Code

跑得有點慢 難道被xu掉了?

BZOJ5055: 膜法師