bzoj 5055: 膜法師
阿新 • • 發佈:2019-01-26
這題膜地也太暴力了吧
話說我天天刷水題是不是沒救了(躺
感覺上 用DP來算(其實我也不知道是不是DP) 怎麼做就很明顯了吧
一個數作為中間數的答案和就是 前面比它小的和 跟它乘起來
一個數作為後面數的答案和就是 前面比它小的 作為中間數的答案和 跟它乘起來
既然不能簡單粗暴地n^2算 那就排序一下 用樹狀陣列來算兩次就好
#include<bits/stdc++.h>
using namespace std;
const int mod=19260817,N=300005;
char B[1<<14],*S=B,*T=B;
#define g (S==T&&(T=(S=B)+fread(B,1,1<<14,stdin),S==T)?-1:*S++)
inline int read(){
int x=0,f=1; char ch=g;
while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=g;}
while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=g;}
return x*f;
}
struct P{int x,y;}a[N]; int b[N],c[N],t[N],n;
int Cmp(P x1,P x2){
return x1.x!=x2.x?x1.x<x2.x :x1.y>x2.y;
}
void add(int x,int u){for(;x<=n;x+=x&-x)t[x]=(t[x]+u)%mod;}
int get(int x){int u=0; for(;x;x-=x&-x)u=(u+t[x])%mod; return u;}
int main(){
n=read(); int i;
for(i=1;i<=n;++i)a[i].x=read()%mod,a[i].y=i;
sort(a+1,a+1+n,Cmp);
for(i=1;i<=n;++i)
b[i]=1 ll*get(a[i].y)*a[i].x%mod,add(a[i].y,a[i].x);
for(i=1;i<=n;++i)t[i]=0;
int ans=0;
for(i=1;i<=n;++i)
c[i]=1ll*get(a[i].y)*a[i].x%mod,ans=(ans+c[i])%mod,add(a[i].y,b[i]);
printf("%d\n",ans);
return 0;
}