fork(1) download
  1. #include <cstdio>
  2. #include <queue>
  3.  
  4. using namespace std;
  5. #define maxn 100000
  6.  
  7. int main(void){
  8.  
  9. priority_queue<int>pq;
  10.  
  11. int e,i,Q,R,N;
  12. long long int f,K,total=0,M[maxn+1];
  13.  
  14. // A maximálisan kifizethető összeg mindig olyan alakú, hogy valamilyen t-re veszem
  15. // a legkisebb t értékű érmét: g[1],..,g[t] és s=g[1]+...+g[t]-ig minden összeg
  16. // kifizethető, de s+1 már nem. Bizonyítás: érmék száma szerinti indukció;
  17. // N=1-re trivi, egyébként pedig, ha e[N]>s+1, akkor az s+1 még mindig nem fizethető ki
  18. // , ha pedig e[N]<=s+1, akkor s-ig minden kifizethető, és [s+1,s+e[N]]-ben is minden
  19. // (haszáljuk e[N]-t). És ezt folytatjuk, ha van s+e[N]+1-nél nem nagyobb, még fel
  20. // nem használt pénzérme. Az is látható, hogy a legkisebb értékű érméket kell választanunk,
  21. // hiszen csak s+1-nél nagyobb érme maradhat benn, ami így minden g[i] éremnél nagyobb
  22. // értékű, és ezzel egyetlen opt. felbontásban sem szerepelhetnek, a többi érmének pedig
  23. // szerepelnie kell, különben s-nél kisebb lesz a max. elérhető összeg.
  24.  
  25. // Prioritásos sorral oldom meg a problémát: O(N*log(N)) időben.
  26. scanf("%d%d",&Q,&N);
  27. for(i=1;i<=N;i++){
  28. scanf("%d",&e);
  29. pq.push(-e);
  30. while(!pq.empty()){
  31. f=-(pq.top());
  32. if(f<=total+1){total+=f;pq.pop();}
  33. else break;
  34. }
  35. M[i]=total;
  36. }
  37. while(Q--){
  38. scanf("%lld%d",&K,&R);
  39. if(K<=M[R])printf("IGEN\n");
  40. else printf("NEM\n");
  41. }
  42.  
  43. return 0;
  44. }
  45.  
Success #stdin #stdout 0s 3536KB
stdin
2 5
4 2 1 13 4
13 4
10 5
stdout
NEM
IGEN