vijos P1459 车展(Treap,中位数)
P1459车展
描述
遥控车是在是太漂亮了,韵韵的好朋友都想来参观,所以游乐园决定举办m次车展。车库里共有n辆车,从左到右依次编号为1,2,…,n,每辆车都有一个展台。刚开始每个展台都有一个唯一的高度h[i]。主管已经列好一张单子:
L1 R1
L2 R2
…
Lm Rm
单子上的(Li,Ri)表示第i次车展将要展出编号从Li到Ri的车。
为了更加美观,展览时需要调整展台的高度,使参展所有展台的高度相等。展台的高度增加或减少1都需花费1秒时间。由于管理员只有一个人,所以只好对每个展台依次操作。每次展览结束后,展台高度自动恢复到初始高度。
请告诉管理员为了举办所有展览,他最少需要花多少时间将展台调整好。
格式
输入格式
第一行为两个正整数n、m。
第二行共n个非负整数,表示第i辆车展台的高度h[i]。
接下来m行每行2个整数Li、Ri(Li≤Ri)。
输出格式
一个正整数,调整展台总用时的最小值。
限制
各个测试点1s
提示
对于50%的数据 n≤500,m≤1000;
对于80%的数据 n≤1000,m≤100000;
对于100%的数据n≤1000,m≤200000;
答案在2^64以内。
【思路】
Treap。
每次展览都是L..R内的中位数作为基准为最优,用Treap提前将所有LR预处理出来。时间为O(n^2logn)
代码奇慢无比 /w\
【代码】
1 #include<cstdio> 2 #include<ctime> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 7 using namespace std; 8 9 typedef long long LL; 10 const int N = 1e3+10; 11 const int INF = 1e8; 12 13 int n,m,h[N],num; 14 LL ans[N][N],tot,cnt,tmp; 15 16 struct Node { 17 Node* ch[2]; 18 int v,r,s,w,sum; 19 Node(int x):v(x) {ch[0]=ch[1]=NULL; s=w=1;sum=x;} 20 int cmp(int x) { 21 if(x==v) return -1; else return x<v? 0:1; 22 } 23 void maintain() { 24 s=w; sum=w*v; 25 if(ch[0]!=NULL) s+=ch[0]->s,sum+=ch[0]->sum; 26 if(ch[1]!=NULL) s+=ch[1]->s,sum+=ch[1]->sum; 27 } 28 }; 29 Node* root; 30 void rotate(Node* &o,int d) { 31 Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d],k->ch[d]=o; 32 o->maintain(),k->maintain(); o=k; 33 } 34 void insert(Node* &o,int x) { 35 if(o==NULL) o=new Node(x); 36 else { 37 int d=o->cmp(x); 38 if(d==-1) {o->w++;o->maintain();return ;} 39 insert(o->ch[d],x); 40 if(o->ch[d]->r > o->r) rotate(o,d^1); 41 } 42 o->maintain(); 43 } 44 int query(Node* o,int x) { 45 int sum,s; 46 if(o->ch[0]==NULL) s=sum=0; else s=o->ch[0]->s,sum=o->ch[0]->sum; 47 if(x>=s+1 && x<=s+o->w) { 48 tmp+=sum; num+=s; 49 return o->v; 50 } 51 else { 52 if(x<=s) return query(o->ch[0],x); 53 else { 54 tmp+=sum+o->v*o->w; 55 num+=s+o->w; 56 return query(o->ch[1],x-s-o->w); 57 } 58 } 59 } 60 61 void read(int& x) { 62 char c=getchar(); int f=1; x=0; 63 while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();} 64 while(isdigit(c)) x=x*10+c-'0',c=getchar(); 65 x*=f; 66 } 67 void init() { 68 FOR(i,1,n) { 69 tot=0; 70 FOR(j,i,n) { 71 tot+=h[j]; insert(root,h[j]); 72 tmp=num=0; 73 int v=query(root,(j-i+2)/2); 74 ans[i][j]+=num*v-tmp; 75 ans[i][j]+=tot-tmp-(j-i+1-num)*v; 76 } 77 root=NULL; 78 } 79 } 80 int main() { 81 read(n),read(m); 82 FOR(i,1,n) read(h[i]); 83 init(); 84 LL anss=0;int x,y; 85 FOR(i,1,m) { 86 read(x),read(y); 87 anss+=ans[x][y]; 88 } 89 cout<<anss; 90 return 0; 91 }
posted on 2016-02-17 12:32 hahalidaxin 阅读(406) 评论(0) 编辑 收藏 举报