CTSC2018 混合果汁
阿新 • • 發佈:2018-12-13
一道簡單的主席樹
考慮按\(d\)排序,然後二分一個答案\(x\).
對\(\geq x\)的\(d\)建一棵主席樹即可.
主席樹上維護兩個資訊:果汁的量和總價.
然後在主席樹上二分即可.
時間複雜度\(O(n*log^2n)\)
程式碼如下
好像才\(38\)行呢
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector> #define N (100010) #define inf (1e18+1) typedef long double ld; typedef long long LL; typedef unsigned long long ull; using namespace std; inline char read(){ static const int IN_LEN=1000000; static char buf[IN_LEN],*s,*t; return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++); } template<class T> inline void read(T &x){ static bool iosig; static char c; for(iosig=false,c=read();!isdigit(c);c=read()){ if(c=='-')iosig=true; if(c==-1)return; } for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0'); if(iosig)x=-x; } inline char readchar(){ static char c; for(c=read();!isalpha(c);c=read()) if(c==-1)return 0; return c; } const int OUT_LEN = 10000000; char obuf[OUT_LEN],*ooh=obuf; inline void print(char c) { if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf; *ooh++=c; } template<class T> inline void print(T x){ static int buf[30],cnt; if(x==0)print('0'); else{ if(x<0)print('-'),x=-x; for(cnt=0;x;x/=10)buf[++cnt]=x%10+48; while(cnt)print((char)buf[cnt--]); } } inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);} #define ls t[rt].ch[0] #define pls t[pre].ch[0] #define rs t[rt].ch[1] #define prs t[pre].ch[1] struct sss{int c,p,l;}a[N]; struct zxs{int ch[2];LL s,w;}t[N*21]; int n,m,T[N],ind; bool cmp(sss A,sss B){return A.c<B.c;} int insert(int pre,int l,int r,int pos,LL v,LL w){ int rt=++ind; t[rt]=t[pre],t[rt].s+=v,t[rt].w+=w; if(l==r)return rt; int mid=(l+r)>>1; if(pos<=mid)ls=insert(pls,l,mid,pos,v,w); else rs=insert(prs,mid+1,r,pos,v,w); return rt; } LL query(int rt,int l,int r,LL s){ if(s>t[rt].s)return inf; if(l==r)return s*(LL)l; int mid=(l+r)>>1; if(s<=t[ls].s)return query(ls,l,mid,s); else return t[ls].w+query(rs,mid+1,r,s-t[ls].s); } LL solve(LL s,LL w){ if(w>s)return -1; int L=0,R=N,ans=0; while(L<=R){ int mid=(L+R)>>1; if(query(T[mid],0,N,w)<=s)L=mid+1,ans=mid; else R=mid-1; } return a[ans].c; } int main(){ read(n),read(m),a[0].c=-1; for(int i=1;i<=n;i++) read(a[i].c),read(a[i].p),read(a[i].l); sort(a+1,a+n+1,cmp); for(int i=n;i>=1;i--) T[i]=insert(T[i+1],0,N,a[i].p,a[i].l,(LL)a[i].p*a[i].l); T[0]=T[1]; while(m--){ LL G,L; read(G),read(L); printf("%lld\n",solve(G,L)); } }