【HDOJ6606】Distribution of books(二分,BIT)

题意:给定一个长为n的数组,要求挑它前缀的一段,将其分成k段,使得每段和的最大值最小

1<=k<=n<=2e5,abs(a[i])<=1e9

思路:

 

 刚开始写了线段树TLE

改维护后缀的BIT也TLE

暴力sort改归并排序才卡过去

怀疑用map离散化不靠谱

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,ll>P;
 11 #define N  400010
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25 
 26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 27       double eps=1e-4;
 28       ll INF=1e10;
 29       ll inf=5e13;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33 map<ll,int> mp;
 34 int t[N],n,k,id;
 35 ll s[M],a[M],b[M],c[N];
 36 
 37 int read()
 38 {
 39    int v=0,f=1;
 40    char c=getchar();
 41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 43    return v*f;
 44 }
 45 
 46 void update(int x,int y)
 47 {
 48     while(x)
 49     {
 50         t[x]=max(t[x],y);
 51         x-=lowbit(x);
 52     }
 53 }
 54 
 55 int query(int x)
 56 {
 57     int res=-2e6;
 58     while(x<=id)
 59     {
 60         res=max(res,t[x]);
 61         x+=lowbit(x);
 62     }
 63     return res;
 64 }
 65 
 66 int isok(ll mid)
 67 {
 68     mp.clear();
 69     int m=0;
 70     rep(i,1,n+1) b[i]=a[i]-mid;
 71     int i=1,j=1;
 72     while(i<=n+1&&j<=n+1)
 73     {
 74         m++;
 75         if(a[i]<b[j])
 76         {
 77             c[m]=a[i];
 78             i++;
 79         }
 80          else
 81          {
 82              c[m]=b[j];
 83              j++;
 84          }
 85     }
 86     while(i<=n+1)
 87     {
 88         c[++m]=a[i];
 89         i++;
 90     }
 91     while(j<=n+1)
 92     {
 93         c[++m]=b[j];
 94         j++;
 95     }
 96     id=1;
 97     mp[c[1]]=1;
 98     rep(i,2,m)
 99      if(c[i]!=c[i-1]) mp[c[i]]=++id;
100     rep(i,1,id) t[i]=-2e6;
101     update(mp[0],0);
102     int ans=0,flag=0;
103     rep(i,1,n)
104     {
105         int tmp=query(mp[s[i]-mid]);
106         ans=max(ans,tmp+1);
107         if(ans>=k) return 1;
108         update(mp[s[i]],tmp+1);
109     }
110     return 0;
111 }
112 
113 int main()
114 {
115     int cas=read();
116     while(cas--)
117     {
118         n=read(),k=read();
119         s[0]=0;
120         rep(i,1,n)
121         {
122             int x=read();
123             s[i]=s[i-1]+x;
124         }
125         rep(i,1,n+1) a[i]=s[i-1];
126         sort(a+1,a+n+1+1);
127         ll l=-1e10,r=1e10,last=1e10;
128         while(l<=r)
129         {
130             ll mid=(l+r)>>1;
131             if(isok(mid)){last=mid; r=mid-1;}
132              else l=mid+1;
133         }
134         printf("%I64d\n",last);
135     }
136 
137     return 0;
138 }

 

posted on 2019-09-27 16:03  myx12345  阅读(263)  评论(0编辑  收藏  举报

导航