zoukankan      html  css  js  c++  java
  • 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo

    枚举长度为m的所有段,尝试用中位数更新答案。

    所以需要数据结构,支持查询k大,以及大于/小于 k大值 的数的和。

    平衡树、权值线段树、权值分块什么的随便呢。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 using namespace std;
     5 typedef long long ll;
     6 struct Point{int v,p;}t[100001];
     7 bool operator < (const Point &a,const Point &b){return a.v<b.v;}
     8 int sumv[350],ma[100001],en,a[100001],b[100001],tot[350],l[350],r[350],num[100001],sum=1,K,n,m;
     9 ll ans=999999999999999999,tAns;
    10 void makeblock()
    11 {
    12     int sz=sqrt(en); if(!sz) sz=1;
    13     for(;sum*sz<en;++sum)
    14       {
    15           l[sum]=r[sum-1]+1; r[sum]=sum*sz;
    16           for(int i=l[sum];i<=r[sum];++i) num[i]=sum;
    17       }
    18     l[sum]=r[sum-1]+1; r[sum]=en;
    19     for(int i=l[sum];i<=r[sum];++i) num[i]=sum;
    20 }
    21 void Insert(const int &x){++b[x]; ++tot[num[x]]; sumv[num[x]]+=(ll)ma[x];}
    22 void Delete(const int &x){--b[x]; --tot[num[x]]; sumv[num[x]]-=(ll)ma[x];}
    23 int Query(const int &x)
    24 {
    25     int cnt=0; ll now=0;
    26     for(int i=1;;i++)
    27       {
    28         cnt+=tot[i]; now+=sumv[i];
    29         if(cnt>=x)
    30           {
    31               cnt-=tot[i]; now-=sumv[i];
    32             for(int j=l[i];;j++)
    33               {
    34                 cnt+=b[j]; now+=(ll)ma[j]*(ll)b[j];
    35                 if(cnt>=x)
    36                   {
    37                       cnt-=b[j]; now-=(ll)ma[j]*(ll)b[j];
    38                       tAns=((ll)ma[j]*(ll)cnt-now);
    39                       return j;
    40                   }
    41               }
    42           }
    43       }
    44 }
    45 void Next_Sum(const int &x)
    46 {
    47     int cnt=0; ll now=0;
    48     for(int i=x+1;i<=r[num[x]];++i) {cnt+=b[i]; now+=(ll)ma[i]*(ll)b[i];}
    49     for(int i=num[x]+1;i<=sum;++i) {cnt+=tot[i]; now+=sumv[i];}
    50     tAns+=(now-(ll)ma[x]*(ll)cnt);
    51 }
    52 int main()
    53 {
    54     scanf("%d%d",&n,&m); K=(m>>1)+1;
    55     for(int i=1;i<=n;++i)
    56       {
    57           scanf("%d",&t[i].v);
    58           t[i].p=i;
    59       } sort(t+1,t+n+1);
    60     ma[a[t[1].p]=++en]=t[1].v;
    61     for(int i=2;i<=n;++i)
    62       {
    63           if(t[i].v!=t[i-1].v) ++en;
    64           ma[a[t[i].p]=en]=t[i].v;
    65       } makeblock();
    66     for(int i=1;i<=m;++i) Insert(a[i]);
    67     int t=Query(K); Next_Sum(t); ans=min(ans,tAns);
    68     for(int i=m+1;i<=n;++i)
    69       {
    70           Delete(a[i-m]); Insert(a[i]);
    71           int t=Query(K);
    72         Next_Sum(t);
    73         ans=min(ans,tAns);
    74       } printf("%lld
    ",ans);
    75     return 0;
    76 }
  • 相关阅读:
    在 macOS High Sierra 10.13 搭建 PHP 开发环境
    给你的网站免费配置上 HTTPS 证书
    将 MacOS 默认的 PHP 版本升级到 7.*
    System.Data.SqlClient.SqlException: 'Incorrect syntax near 'OFFSET'.
    IIS7/8 HTTP Error 500.19 错误 0x80070021 错误代码:0x8007000d
    http error 502.5
    信用卡逾期了怎么办 ?逾期记录“修复”的两大原则
    APP多开教程
    lua调用不同lua文件中的函数
    Lua 用指定字符或字符串分割输入字符串,返回包含分割结果的数组
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4148233.html
Copyright © 2011-2022 走看看