Portal: Http://codeforces.com/problemset/problem/609/D
(If you need to reprint, please indicate the source, thank you O (∩_∩) o )
Test instructions
Nura want to buy K a gadget, she has s a burles (a currency), there are m small gadgets for her to choose to buy, but each gadget can only be purchased with dollars or pounds, So every time when the purchase of the Nura will be the exchange rate of her hand burles to dollars or pounds, and each day the exchange rate is not the same, give n days, and this n days burles into dollars and pounds ratio, Ask if you can buy K gadgets with the Burles on your hand in these n days, if not, output-1; If so, output the minimum number of days (that is, the minimum number of days that can make Nura buy K gadgets), and in the next m line, output two numbers in turn, The number of gadgets purchased (in the order they were given) and the date the gadget was bought (i.e. the day of the week). -You can buy any number of gadgets on the same day.
Thinking and analysis of solving problems:
Note that the data range is 2e5, and obviously need some way to compare the "days", the direct enumeration must be very virtual, so the use of two points.
(Here is the correct posture for the two points written by the classmate:
int l,r,m;
while (r-l>1) {
M= ((r-l) >>1) +l;
if () r=m;
else l=m;
}
)
After you have determined the number of days to enumerate by two points, you need to determine the contents of the two points. Because a day can buy more than one, so obviously should find the highest exchange rate of the day, that is, the interval minimum, here with the St algorithm, O (NLOGN) preprocessing, O (1) query-won the interval Burles redemption dollars and pounds the most "cost" of the day, is to determine the minimum cost of buying k gadgets, there is no easy way to think of, can only use O (MLOGM) preprocessing (sort), each time O (k) to get the cost. With the structure of the storage gadget Type,cost and num (numbered, back output used), and then sort-overload less than the number, first by the type row, and then by the cost row, record type==2 the first gadget corresponding subscript ter, and then only need to compare the time of each calculation, It is guaranteed to get the minimum cost (see the code for details)-After the minimum cost, compare it to s to see if the interval is feasible.
Code implementation process and reflection:
It feels like the pit is almost trampled on.
1, the calculation of the minimum cost, will cause an int overflow, to use a long long.
2, not the pit: the original title output part of the "number of gadget", refers to the numbers of gadgets, not the number (gadget no s), drunk.
4, Details: When calculating the minimum cost, while loop should be j<m instead of J<n (J for Ter as the starting point subscript, I starting from 0), and WA pitch.
3, two minutes, because while in the r-l>1, so when n is 1 o'clock, will be directly skip the two-point judgment. And, if there is a viable answer, it must be two minutes after the end of the L or R, the first sentence L, if l do not judge R; if not, it means that there is no correct result. Here again wa a few hair, by two points teach a person.
The code is as follows:
1#include <iostream>2#include <cstdio>3#include <algorithm>4#include <cstring>5 using namespacestd;6typedefLong Longll;7 Const intn=2e5+Ten, m= the;8 structgadget{9 intType,cost,num;Ten BOOL operator< (ConstGadget g)Const{ One returntype==g.type?cost<g.cost:type<G.type; A } - }g[n]; - intN,m,k,s,ter,a[n],b[n],da[n][m],db[n][m]; the voidinit () { - for(intI=0; i<n;i++) da[i][0]=a[i],db[i][0]=B[i]; - for(intj=1;(1<<J) <=n;j++) - for(intI=0; i+ (1<<J)-1<n;i++){ +Da[i][j]=min (da[i][j-1],da[i+ (1<< (J-1))][j-1]); -Db[i][j]=min (db[i][j-1],db[i+ (1<< (J-1))][j-1]); + } A } at intRMQ (intLintRintD[n][m]) { - intk=0; - while((1<< (k +1)) <=r-l+1) k++; - returnMin (d[l][k],d[r-(1<<K) +1][k]); - } - BOOLCheck (ll p1,ll p2) { in intCnt=0; -ll tot=0; to intI=0, j=ter; + while(j<m) { - if(i==ter| | CNT==K) Break; the if(g[i].cost*p1<=g[j].cost*p2) *tot+=g[i++].cost*P1; $ Elsetot+=g[j++].cost*P2;Panax Notoginsengcnt++; - } the if(cnt<k) { + if(i<ter) Swap (i,j), swap (P1,P2); A while(cnt<k) tot+=p2*g[j++].cost,cnt++; the } + returntot<=s; - } $ intMain () { $ //freopen ("In.txt", "R", stdin); - while(~SCANF ("%d%d%d%d",&n,&m,&k,&s)) { - for(intI=0; i<n;i++) thescanf"%d", A +i); - for(intI=0; i<n;i++)Wuyiscanf"%d", B +i); theTer=0; - for(intI=0; i<m;i++){ Wuscanf"%d%d",&g[i].type,&g[i].cost); - if(g[i].type==1) ter++; Aboutg[i].num=i+1; $ } - init (); -Sort (g,g+m); - BOOLflag=false; A intL=0, r=n-1, mid; + ll P1,p2; the while(r-l>1){ -Mid= (r-l) >>1)+L; $P1=RMQ (0, Mid,da), P2=RMQ (0, mid,db); the if(check (P1,P2)) R=mid; the ElseL=mid; the } theP1=RMQ (0, L,da), P2=RMQ (0, l,db); - if(check (P1,P2)) flag=true; in Else{ theP1=RMQ (0, R,da), P2=RMQ (0, r,db); the if(check (P1,P2)) flag=true; About } the if(flag) { the intd1,d2; the for(intI=0; i<n;i++)if(a[i]==p1) { +d1=i+1; Break; - } the for(intI=0; i<n;i++)if(b[i]==p2) {Bayid2=i+1; Break; the } theprintf"%d\n", Max (D1,D2)); - intCnt=0, tot=0; - intI=0, j=ter; the while(j<m) { the if(i==ter| | CNT==K) Break; the if(g[i].cost*p1<=g[j].cost*p2) { thecnt++; -printf"%d%d\n", g[i++].num,d1); the } the Else{ thecnt++;94printf"%d%d\n", g[j++].num,d2); the } the } the if(cnt<k) {98 if(i<ter) Swap (D1,D2), swap (I,J); About while(cnt<k) printf ("%d%d\n", G[J++].NUM,D2), cnt++; - }101 }102 ElsePuts"-1");103 }104 return 0; the}View Code
Codeforces 609D being a two-point teacher