首页 > 代码库 > 【权值分块】bzoj1588 [HNOI2002]营业额统计
【权值分块】bzoj1588 [HNOI2002]营业额统计
权值分块就是快……Rank5……
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 #define N 38001 6 #define INF 2147483647 7 #define min(a,b) (((a)<(b))?(a):(b)) 8 struct Point{int v,p;}t[N]; 9 bool operator < (const Point &a,const Point &b){return a.v<b.v;}10 int n,ma[N],a[N],en,sum,sz,l[201],r[201],sumv[201],num[N],b[N],ans;11 inline void R(int &x){12 char c=0;int f=1;13 for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)f=-1;14 for(x=0;c>=‘0‘&&c<=‘9‘;c=getchar())(x*=10)+=(c-‘0‘);15 x*=f;16 }17 void makeblock()18 {19 sz=sqrt(en); if(!sz) sz=1;20 for(sum=1;sum*sz<en;sum++)21 {22 l[sum]=r[sum-1]+1;23 r[sum]=sz*sum;24 for(int i=l[sum];i<=r[sum];i++) num[i]=sum;25 }26 l[sum]=r[sum-1]+1;27 r[sum]=en;28 for(int i=l[sum];i<=r[sum];i++) num[i]=sum;29 }30 inline void Insert(const int &x){b[x]++; sumv[num[x]]++;}31 inline int Next(const int &x)32 {33 if(b[x]>1) return x;34 for(int i=x+1;i<=r[num[x]];i++) if(b[i]) return i;35 for(int i=num[x]+1;i<=sum;i++) if(sumv[i])36 for(int j=l[i];;j++)37 if(b[j]) return j;38 return INF;39 }40 inline int Pre(const int &x)41 {42 if(b[x]>1) return x;43 for(int i=x-1;i>=l[num[x]];i--) if(b[i]) return i;44 for(int i=num[x]-1;i>=1;i--) if(sumv[i])45 for(int j=r[i];;j--)46 if(b[j]) return j;47 return INF;48 }49 int main()50 {51 R(n); for(int i=1;i<n;i++)52 {53 R(t[i].v);54 t[i].p=i;55 }56 if(scanf("%d",&t[n].v)==EOF) t[n].v=0; t[n].p=n;57 sort(t+1,t+n+1);58 ma[a[t[1].p]=++en]=t[1].v;59 for(int i=2;i<=n;i++)60 {61 if(t[i].v!=t[i-1].v) en++;62 ma[a[t[i].p]=en]=t[i].v;63 } makeblock();64 Insert(a[1]); ans+=ma[a[1]];65 for(int i=2;i<=n;i++)66 {67 Insert(a[i]);68 int Up=Next(a[i]),Down=Pre(a[i]);69 if(Up==INF) ans+=(ma[a[i]]-ma[Down]);70 else if(Down==INF) ans+=(ma[Up]-ma[a[i]]);71 else ans+=min(ma[Up]-ma[a[i]],ma[a[i]]-ma[Down]);72 } printf("%d\n",ans);73 return 0;74 }
【权值分块】bzoj1588 [HNOI2002]营业额统计
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。