BZOJ5177: [Jsoi2013]貪心的導遊
阿新 • • 發佈:2018-03-21
總數 購物 mat ret 一點 不能 turn 謙虛 商品
5 5
2 4 6 8 10
0 1 2
1 4 3
2 4 2
1 1 9
0 4 7
2
0
4
6
第一個旅遊團, 2 個人, 0 號商店到 1 號商店的區間。若去 1 號商店,共 2 件商品,每人買 1 件,剩 0 件
。若去 2 號商店,共 4 件商品,每人買 2 件,剩 0 件。所以,小 Z 最多獲贈 0 件。
第二個旅遊團, 3 個人,小 Z 選擇帶他們去 4 號商店,共 8 件商品,每人買 2 件商品(因為每人 3 件不夠)
,剩下 2 件,小 Z 最多獲贈就是 2 件。 可以驗證去其它商店小 Z 最多獲贈的商品不會達到 2 件。
題目傳送門
話說A這種題目很爽啊~~~
今天早上翻出來這道題,看了看,就想暴力
暴力求出每個數mod1~1000的值,用主席樹查最大值,然後在班上吼了一嗓子。。。
結果隔壁的肉絲也開始搞這個,他竟然做的比我快!!(這就是你頹飛劍問道的原因???)
然後一看內存,哎呀媽呀,這n<=1000000是要上天。。。
其實這個還是可以用主席樹做的,同樣從p下手即可
枚舉一下問問主席樹這東西在不在即可
40s的題真親切
代碼如下:
Description
南京有一條著名的購物街。購物街嘛,就是一排整齊的商店啦~ 導遊小Z每次都會把遊客團帶到購物街裏走一段,然後選擇一個商店進去購物。小Z接待的遊客都是購物狂,他們恨 不得將店內的商品洗劫一空,也就是說,只要他們能買,就一定會繼續買(錢夠不夠你不用考慮,他們都有信用卡 可以透支)。但是有一點,他們都非常講究平等、很謙虛,每個人都不能忍受比別人多買什麽東西或者少買什麽東 西,於是他們每個人最後買的商品數量都是一樣的。這雖然導致他們沒辦法每次都把商店搬空,但是每次已經給店 家帶來一大筆生意了,店家已經非常感謝了!為了表示感謝,店家決定把遊客們買完之後剩下來那幾件沒賣掉的商 品就送給導遊小Z了。貪心的小Z自然希望自己能獲贈的商品數量越大越好啦~現在告訴你這一排共n個商店(標號為 0到n-1)每個商店裏的商品總數,每次小Z會帶一批共p個遊客的旅遊團,到其中u號商店和v號商店之間逛一逛,請 你幫小Z在所逛的商店區間內選擇一個,告訴小Z他最多能獲贈多少件商品。
Input
第一行,包含兩個整數n、m,分別表示商店個數、小Z帶來的旅遊團個數。 接下來一行,包含n個整數ai(i=0,1,……,n-1),表示第i個商店的商品總數。 接下來m行,每行三個整數u、v、p(0≤u,v≤n-1,2≤p≤1000) 表示這個旅遊團逛u號商店和v號商店之間的商店(包含u、v),且這個旅遊團的人數為p。 n≤1000000, m≤50000, 0≤ai≤1000, 2≤p≤1000
Output
共輸出m行,每行一個整數,第i行輸出第i個旅遊團購物後,小Z最多能獲贈的商品數量。
Sample Input
2 4 6 8 10
0 1 2
1 4 3
2 4 2
1 1 9
0 4 7
Sample Output
02
0
4
6
第一個旅遊團, 2 個人, 0 號商店到 1 號商店的區間。若去 1 號商店,共 2 件商品,每人買 1 件,剩 0 件
。若去 2 號商店,共 4 件商品,每人買 2 件,剩 0 件。所以,小 Z 最多獲贈 0 件。
第二個旅遊團, 3 個人,小 Z 選擇帶他們去 4 號商店,共 8 件商品,每人買 2 件商品(因為每人 3 件不夠)
,剩下 2 件,小 Z 最多獲贈就是 2 件。 可以驗證去其它商店小 Z 最多獲贈的商品不會達到 2 件。
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; struct ZhuXi{ int lc,rc,c; }t[21000000];int cnt; int rt[2100000]; void Link(int &u,int l,int r,int p) { if(u==0)u=++cnt; t[u].c++; if(l==r)return ; int mid=(l+r)/2; if(p<=mid)Link(t[u].lc,l,mid,p); else Link(t[u].rc,mid+1,r,p); } void merge(int &u1,int u2) { if(u1==0){u1=u2;return ;} if(u2==0)return ; t[u1].c+=t[u2].c; merge(t[u1].lc,t[u2].lc); merge(t[u1].rc,t[u2].rc); } int findans(int u1,int u2,int l,int r,int k) { if(t[u1].c-t[u2].c==0)return 0; if(l==r)return l; int lcx=t[u1].lc,rcx=t[u1].rc,lcy=t[u2].lc,rcy=t[u2].rc; int mid=(l+r)/2; if(k<=mid)return findans(lcx,lcy,l,mid,k); else { int tmp=findans(rcx,rcy,mid+1,r,k); if(tmp==0)return findans(lcx,lcy,l,mid,k); } } int n,m; int main() { scanf("%d%d",&n,&m);cnt=0; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); Link(rt[i],0,2000,x); merge(rt[i],rt[i-1]); } while(m--) { int u,v,p;int ans=0; scanf("%d%d%d",&u,&v,&p);u++,v++; for(int i=1;i*p<=2000;i++) ans=max(ans,findans(rt[v],rt[u-1],0,2000,p*i-1)-p*(i-1)); printf("%d\n",ans); } return 0; }
by_lmy
BZOJ5177: [Jsoi2013]貪心的導遊