【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 }
null