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)。

输出格式

一个正整数,调整展台总用时的最小值。

样例1

样例输入1[复制]

 
6 4
4 1 2 13 0 9
1 5
2 6
3 4
2 2

样例输出1[复制]

 
48

限制

各个测试点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 }
原文地址:https://www.cnblogs.com/lidaxin/p/5194957.html