BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)

 

BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)

分类: 左偏树   173人阅读  评论(0)  收藏  举报

目录(?)[+]

1367: [Baltic2004]sequence

Time Limit: 20 Sec   Memory Limit: 64 MB
Submit: 521   Solved: 159
[ Submit][ Status]

Description

Input

Output

一个整数R

Sample Input

7
9
4
8
20
14
15
18

Sample Output

13

HINT

所求的Z序列为6,7,8,13,14,15,18.
R=13


左偏树+1

这题裸裸的左偏树,我却各种WA。。。。

结果发现 左偏树合并 a*b==0 会乘爆掉。。。掉节操。。。。。

[cpp]  view plain copy
  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<cstdlib>  
  4. #include<algorithm>  
  5. #include<functional>  
  6. #include<iostream>  
  7. #include<cmath>  
  8. using namespace std;  
  9. #define For(i,n) for(int i=1;i<=n;i++)  
  10. #define Fork(i,k,n) for(int i=k;i<=n;i++)  
  11. #define Rep(i,n) for(int i=0;i<n;i++)  
  12. #define ForD(i,n) for(int i=n;i;i--)  
  13. #define RepD(i,n) for(int i=n;i>=0;i--)  
  14. #define Forp(x) for(int p=pre[x];p;p=next[p])  
  15. #define Lson (x<<1)  
  16. #define Rson ((x<<1)+1)  
  17. #define MEM(a) memset(a,0,sizeof(a));  
  18. #define MEMI(a) memset(a,127,sizeof(a));  
  19. #define MEMi(a) memset(a,128,sizeof(a));  
  20. #define INF (2139062143)  
  21. #define F (100000007)  
  22. #define MAXN (1300000+10)  
  23. long long mul(long long a,long long b){return (a*b)%F;}  
  24. long long add(long long a,long long b){return (a+b)%F;}  
  25. long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}  
  26. typedef long long ll;  
  27. int father[MAXN];  
  28. int getfather(int x)  
  29. {  
  30.     if (father[x]==x) return x;  
  31.     father[x]=getfather(father[x]);  
  32.     return father[x];  
  33. }  
  34. struct node  
  35. {  
  36.     ll v;  
  37.     int dis,ch[2];  
  38.     node():v(0),dis(0){ch[0]=ch[1]=0;}  
  39.     node(ll _v):v(_v),dis(0){ch[0]=ch[1]=0;}  
  40. }q[MAXN];  
  41. int merge(int a,int b)  
  42. {  
  43.     if (a==0||b==0) return a+b;  
  44.     if (q[a].v<q[b].v) swap(a,b);  
  45.     q[a].ch[1]=merge(q[a].ch[1],b);  
  46.     if (q[q[a].ch[0]].dis<q[q[a].ch[1]].dis) swap(q[a].ch[0],q[a].ch[1]);  
  47.     if (q[a].ch[1]) q[a].dis=q[q[a].ch[1]].dis+1;else q[a].dis=0;  
  48.     return a;  
  49. }  
  50. int root[MAXN],tot=0;  
  51. int pop(int a)  
  52. {  
  53.     int p=merge(q[a].ch[0],q[a].ch[1]);  
  54.     return p;  
  55. }  
  56. int n,siz[MAXN],l[MAXN],r[MAXN];  
  57. ll a[MAXN];  
  58. ll abs2(ll a,ll b){return a-b>0?a-b:b-a;}  
  59. int main()  
  60. {  
  61. //  freopen("bzoj1367.in","r",stdin);  
  62.     scanf("%d",&n);  
  63.     For(i,n) scanf("%lld",&a[i]),a[i]-=(long long)i,father[i]=i,q[i].v=a[i];  
  64.     For(i,n)  
  65.     {  
  66.         siz[++tot]=1;root[tot]=i;l[tot]=r[tot]=i;  
  67.         while (tot>1&&q[root[tot]].v<=q[root[tot-1]].v)  
  68.         {  
  69.             int ru=root[tot-1],rv=root[tot];  
  70.             Fork(j,l[tot],r[tot])  
  71.             {  
  72.                 q[j]=node(a[j]);  
  73.                 ru=merge(ru,j);  
  74.             }  
  75.             siz[tot-1]+=r[tot]-l[tot]+1;r[tot-1]=r[tot];tot--;  
  76.             while (siz[tot]>(r[tot]-l[tot]+2)/2) ru=pop(ru),siz[tot]--;  
  77.             root[tot]=ru;             
  78.         }  
  79. //      For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;  cout<<endl;  
  80.     }  
  81.     //For(i,n) cout<<a[i]<<' ';cout<<endl;  
  82.     //For(i,tot) cout<<siz[i]<<' ';cout<<endl;  
  83.       
  84.     //For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;      
  85.       
  86.     ll ans=0;  
  87.     For(i,tot)  
  88.     {  
  89.         Fork(j,l[i],r[i]) ans+=abs2(q[root[i]].v,a[j]);  
  90.     }  
  91.     printf("%lld\n",ans);  
  92.     return 0;  
  93. }  

第二Sol-贪心:

假想有2数列A,B

A的中位数<B的中位数 

A的中位数>(B+C)的中位数 

则(A+B+C)的中位数≤A的中位数<B的中位数

所以A中位数,B中位数往上的部分去掉,不影响结果


[cpp]  view plain copy
  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<cstdlib>  
  4. #include<algorithm>  
  5. #include<functional>  
  6. #include<iostream>  
  7. #include<cmath>  
  8. using namespace std;  
  9. #define For(i,n) for(int i=1;i<=n;i++)  
  10. #define Fork(i,k,n) for(int i=k;i<=n;i++)  
  11. #define Rep(i,n) for(int i=0;i<n;i++)  
  12. #define ForD(i,n) for(int i=n;i;i--)  
  13. #define RepD(i,n) for(int i=n;i>=0;i--)  
  14. #define Forp(x) for(int p=pre[x];p;p=next[p])  
  15. #define Lson (x<<1)  
  16. #define Rson ((x<<1)+1)  
  17. #define MEM(a) memset(a,0,sizeof(a));  
  18. #define MEMI(a) memset(a,127,sizeof(a));  
  19. #define MEMi(a) memset(a,128,sizeof(a));  
  20. #define INF (2139062143)  
  21. #define MAXN (1000000+10)  
  22. typedef long long ll;  
  23. struct node  
  24. {  
  25.     int v,dis,ch[2];  
  26.     node():v(0),dis(0){ch[0]=ch[1]=0;}  
  27.     node(int _v):v(_v),dis(0){ch[0]=ch[1]=0;}  
  28. }q[MAXN];  
  29. int merge(int a,int b)  
  30. {  
  31.     if (a==0||b==0) return a+b;  
  32.     if (q[a].v<q[b].v) swap(a,b);  
  33.     q[a].ch[1]=merge(q[a].ch[1],b);  
  34.     if (q[q[a].ch[0]].dis<q[q[a].ch[1]].dis) swap(q[a].ch[0],q[a].ch[1]);  
  35.     q[a].dis=q[q[a].ch[1]].dis+1;  
  36.     return a;  
  37. }  
  38. int root[MAXN],tot=0;  
  39. int pop(int a)  
  40. {  
  41.     int p=merge(q[a].ch[0],q[a].ch[1]);  
  42.     return p;  
  43. }  
  44. int n,siz[MAXN]={0},l[MAXN]={0},r[MAXN]={0};  
  45. int a[MAXN]={0};  
  46. ll abs2(ll a,ll b){return a-b>0?a-b:b-a;}  
  47. int main()  
  48. {  
  49.     freopen("bzoj1367.in","r",stdin);  
  50.     scanf("%d",&n);  
  51.     For(i,n)  
  52.     {  
  53.         scanf("%d",&a[i]),a[i]-=i;q[i].v=a[i];  
  54.     }  
  55.     For(i,n)  
  56.     {  
  57.         siz[++tot]=1;root[tot]=i;l[tot]=r[tot]=i;  
  58.         while (tot>1&&q[root[tot-1]].v>q[root[tot]].v)  
  59.         {  
  60.             int ru=root[tot-1],rv=root[tot];  
  61.             /* 
  62.             Fork(j,l[tot],r[tot]) 
  63.             { 
  64.                 q[j]=node(a[j]); 
  65.                 ru=merge(ru,j); 
  66.             }*/  
  67.             ru=merge(ru,rv);int b=((r[tot-1]-l[tot-1]+1)%2)+((r[tot]-l[tot]+1)%2);  
  68.             siz[tot-1]+=siz[tot];r[tot-1]=r[tot];tot--;  
  69.             if (b==2) ru=pop(ru),siz[tot]--;  
  70.             root[tot]=ru;             
  71. //      For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;  cout<<endl;  
  72.         }  
  73.     }  
  74. //  For(i,n) cout<<a[i]<<' ';cout<<endl;  
  75. //  For(i,tot) cout<<siz[i]<<' ';cout<<endl;  
  76.       
  77. //  For(i,tot) cout<<l[i]<<' '<<r[i]<<' '<<q[root[i]].v<<endl;    
  78.       
  79.     ll ans=0;  
  80.     For(i,tot)  
  81.     {  
  82.         Fork(j,l[i],r[i]) ans+=abs2(q[root[i]].v,a[j]);  
  83.     }  
  84.     cout<<ans<<endl;  
  85.     return 0;  
  86. }  

你可能感兴趣的:(左偏树)