Advertisement
RaFiN_

Sum over Subset DP

Dec 29th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.40 KB | None | 0 0
  1. /** Monster.cpp
  2.  *  Codechef : JAN18
  3.  *
  4.  *  Attribution : https://www.codechef.com/viewsolution/16996418
  5.  *
  6.  *  ShivamKD
  7.  *
  8.  */
  9.  
  10. #include <bits/stdc++.h>
  11. using namespace std;
  12. #define ll long long
  13.  
  14. const int N_MAX = (1<<17) + 1;
  15. const int MAX = (1e9) + 3;
  16. const int mask = (1<<17)-1;
  17. const int BIT = 18;
  18. const int Q_MAX = (1<<18) + 1;
  19.  
  20. // To store how much died at that query.
  21. int answer[Q_MAX];
  22. // Height
  23. int h[N_MAX];
  24. // Query : x,y
  25. int query[Q_MAX][2];
  26. // For SOS DP
  27. int bitmask[Q_MAX];
  28.  
  29. int main()
  30. {
  31.     int n;
  32.     cin>>n;
  33.    
  34.     // Taking height as input
  35.     for(int i=0;i<n;i++) cin>>h[i];
  36.  
  37.     int q;
  38.     cin>>q;
  39.  
  40.     //Queries
  41.     for(int i=0;i<q;i++)
  42.     {
  43.         cin>>query[i][0]>>query[i][1];
  44.         // If the value is greater than
  45.         // 1<<17 trim it. As index can
  46.         // be at max 1<<17
  47.         query[i][0] &= mask;
  48.     }
  49.  
  50.     // Divide queires in blocks.
  51.     int block_size = 1000, total_block = q/block_size + 1, index = 0;
  52.  
  53.     int duplicate ;
  54.     // Traversing through each block
  55.     // SQRT time
  56.     for(int in_block = 0; in_block<total_block; in_block++)
  57.     {
  58.         // For each block keep the bitmask 0 initially
  59.         memset(bitmask, 0 , sizeof(bitmask));
  60.  
  61.         duplicate = index;
  62.        
  63.         // Traverse through the block
  64.         // SQRT Time
  65.         for(int i = 0;(i<block_size) && (index<q); i++,index++)
  66.         {
  67.             // Store the updates by the query.
  68.             bitmask[query[index][0]] += query[index][1];
  69.         }
  70.  
  71.         // SOS DP Procedure (Reverse)
  72.         for(int bit = 0;bit<BIT;bit++)
  73.         {
  74.  
  75.             for(int i=mask;i>=0;i--)
  76.             {
  77.                 // If the ith bit is unset
  78.                 // Add the result from setting that bit
  79.                 // to current value.
  80.                 // For example i=10 (1010), this shall also
  81.                 // be updated by 11 (1011).
  82.                 // i.e. 1010^1 = 1011
  83.                 if(!((i>>bit)&1))
  84.                 {
  85.                     bitmask[i]+=bitmask[i^(1<<bit)];
  86.                     // As Height cannot be greater than 1e9
  87.                     bitmask[i]=min(bitmask[i],MAX);
  88.                 }
  89.             }
  90.         }// Time : 18 * (2^17)
  91.        
  92.         // After the above loop all the index of the bitmsk store
  93.         // the total update due to the current block.
  94.  
  95.         int pos = duplicate;
  96.        
  97.         // Travering through each height
  98.         // TO check which which index will decrease due to this block.
  99.         for(int i=0;i<n;i++)
  100.         {
  101.             // If already less than zero
  102.             // We need not care how much it has
  103.             // Decreased.
  104.             // Continue
  105.             if(h[i]<=0)
  106.                 continue;
  107.             // Decrease it
  108.             // By the total height contributed by
  109.             // this block
  110.             h[i]-=bitmask[i];
  111.            
  112.             // If this is greater than 0.
  113.             // Continue
  114.             if(h[i]>0)
  115.                 continue;
  116.             // If less than or equal to zero
  117.             // we need to check after which query we
  118.             // came to this less than zero value.
  119.  
  120.             // Current : To count (sequential) decrease by this block
  121.             int current = 0;
  122.             duplicate = pos;
  123.             //index = duplicate;
  124.  
  125.             // Traverse through each query in the current block
  126.             for(int j=0;(j<block_size) && (duplicate<q); j++,duplicate++)
  127.             {
  128.                 // If this query has an effect in
  129.                 // the decrease.
  130.                 if((i&query[duplicate][0])==i)
  131.                     current+=query[duplicate][1];
  132.  
  133.                 // If after this query
  134.                 // the value of Height became non positive.
  135.                 if(((bitmask[i] + h[i]) - current)<=0)
  136.                 {
  137.                     // Add 1 to this query in the answer.
  138.                     // Denoting that this query resulted in decrease
  139.                     // answer[duplicate] heights.
  140.                     answer[duplicate]++;
  141.                     break;
  142.                 }
  143.             }
  144.         }
  145.     }
  146.  
  147.     // Initially all alive
  148.     int left = n;
  149.  
  150.     // Traverse through all queries.
  151.     for(int i=0;i<q;i++)
  152.     {
  153.         // Decrease the hieght which became non
  154.         // positive after this query
  155.         left = left - answer[i];
  156.         cout<<left<<"\n";
  157.     }
  158.     return 0;
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement