大讨论题。。写了一点就弃疗了。。按权值大小枚举中间那个数,根据两边的值与中间那个值得大小关系可以分出3类,反过来又是三类,一共九类。。
发现每个位置的贡献最多变化两次。。。发现要取最值不能离散化就弃疗了。。
记个题号以后再补吧。。bzoj1099
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const int N = 50100; 6 struct Node{ 7 int x,y; 8 Node(){} 9 Node(int x,int y):x(x),y(y){} 10 }nod[N]; 11 ll seg[3][N<<2],sum[3][N<<2]; 12 int n,a[N],rank[N],len,finger; 13 ll sum,ans[N]; 14 bool cmp(const Node &a,const Node &b){ 15 return a.x < b.x; 16 } 17 void init(); 18 void insert(int,int,int,int,int,int); 19 void update(int,int); 20 int main(){ 21 scanf("%d",&n); 22 for (int i = 1;i <= n;i++) scanf("%d",&a[i]); 23 for (int i = 1;i < n;i++) sum += abs(a[i]-a[i+1]); 24 if (n == 2){ 25 printf("%lld %lld ",sum,sum); 26 return 0; 27 } 28 init(); 29 30 for (int i = 2;i < n;i++) 31 nod[i] = Node(a[i],i); 32 sort(nod+2,nod+n,cmp); 33 34 len = 1; 35 for (int i = 3;i < n;i++) 36 if (nod[i].x != nod[i-1].x) rank[i-1] = len++; 37 else rank[i-1] = len; 38 rank[n-1] = len; 39 40 finger = nod[2].x; 41 for (int i = 2;i < n;i++){ 42 if (abs(nod[i].y-nod[2].y) != 1){ 43 int opt; 44 if (min(a[nod[i].y-1],a[nod[i].y+1]) >= nod[2].x) opt = 0; 45 else if (max(a[nod[i].y-1],a[nod[i].y+1) <= nod[2].x) opt = 2; 46 else opt = 1; 47 insert(1,1,n,rank[nod[i].y],nod[i].y,opt); 48 } 49 } 50 for (int i = 2;i < n;i++){ 51 int l = rank[nod[i].y-1],r = rank[nod[i].y+1]; 52 if (l > r) swap(l,r); 53 ll w1 = getans(1,1,n,1,l,0)-nod[i].x*2+a[nod[i].y-1]+a[nod[i].y+1]; 54 ll w2 = getans(1,1,n,l,r,0)-nod[i].x*2+abs(a[nod[i].y-1]-a[nod[i].y+1]); 55 } 56 for (int i = 1;i <= n;i++) printf("%d ",sum+min(0,ans[i])); 57 return 0; 58 } 59 void init(){ 60 for (int i = 2;i < n-1;i++){ 61 ll w = abs(a[i]-a[i+2])+abs(a[i-1]-a[i+1])-abs(a[i]-a[i-1])-abs(a[i+1]-a[i+2]); 62 ans[i] = min(ans[i],w); 63 ans[i+1] = min(ans[i+1],w); 64 } 65 66 for (int i = 2;i < n-1;i++){ 67 ll w = abs(a[i+1]-a[1])+abs(a[i-1]-a[1])+abs(a[2]-a[i])-abs(a[2]-a[1])-abs(a[i-1]-a[i])-abs(a[i+1]-a[i]); 68 ans[1] = min(ans[1],w); 69 ans[i] = min(ans[i],w); 70 w = abs(a[i+1]-a[n])+abs(a[i-1]-a[n])+abs(a[n-1]-a[i])-abs(a[n-1]-a[n])-abs(a[i-1]-a[i])-abs(a[i+1]-a[i]); 71 ans[n] = min(ans[n],w); 72 ans[i] = min(ans[i],w); 73 } 74 75 ll w = abs(a[2]-a[n])+abs(a[1]-a[n-1])-abs(a[1]-a[2])-abs(a[n]-a[n-1]); 76 ans[1] = min(ans[1],w); 77 ans[n] = min(ans[n],w); 78 w = abs(a[3]-a[1])-abs(a[3]-a[2]); 79 ans[1] = min(ans[1],w); 80 ans[2] = min(ans[2],w); 81 w = abs(a[n-2]-a[n])-abs(a[n-2]-a[n-1]); 82 ans[n] = min(ans[n],w); 83 ans[n-1] = min(ans[n-1],w); 84 } 85 void insert(int p,int l,int r,int x,int y,int opt){ 86 if (l == r){ 87 sum[opt][l] += a[y]; 88 if (opt == 0) seg[opt][l] += a[y-1]+a[y+1]; 89 if (opt == 1) seg[opt][l] += abs(a[y-1]-a[y+1]); 90 if (opt == 2) seg[opt][l] -= a[y-1]+a[y+1]; 91 return; 92 } 93 int mid = l + r >> 1; 94 if (x <= mid) insert(p<<1,l,mid,x,y,opt); 95 else insert(p<<1|1,mid+1,r,x,y,opt); 96 update(p,opt); 97 } 98 void update(int p,int opt){ 99 int u = p<<1,v = u|1; 100 sum[opt][p] = sum[opt][u]+sum[opt][v]; 101 seg[opt][p] = seg[opt][u]+seg[opt][v]; 102 }