Monday, 28 September 2015

****(vvi) Glass Carvin

 Glass Carvin

http://codeforces.com/problemset/problem/527/C

Leonid wants to become a glass carver (the person who creates beautiful artworks by cutting the glass). He already has a rectangular wmm  ×  h mm sheet of glass, a diamond glass cutter and lots of enthusiasm. What he lacks is understanding of what to carve and how.
In order not to waste time, he decided to practice the technique of carving. To do this, he makes vertical and horizontal cuts through the entire sheet. This process results in making smaller rectangular fragments of glass. Leonid does not move the newly made glass fragments. In particular, a cut divides each fragment of glass that it goes through into smaller fragments.
After each cut Leonid tries to determine what area the largest of the currently available glass fragments has. Since there appear more and more fragments, this question takes him more and more time and distracts him from the fascinating process.
Leonid offers to divide the labor — he will cut glass, and you will calculate the area of the maximum fragment after each cut. Do you agree?
Input
The first line contains three integers w, h, n (2 ≤ w, h ≤ 200 0001 ≤ n ≤ 200 000).
Next n lines contain the descriptions of the cuts. Each description has the form H y or V x. In the first case Leonid makes the horizontal cut at the distance y millimeters (1 ≤ y ≤ h - 1) from the lower edge of the original sheet of glass. In the second case Leonid makes a vertical cut at distance x (1 ≤ x ≤ w - 1) millimeters from the left edge of the original sheet of glass. It is guaranteed that Leonid won't make two identical cuts.
Output
After each cut print on a single line the area of the maximum available glass fragment in mm2.
Sample test(s)
input
4 3 4
H 2
V 2
V 3
V 1
output
8
4
4
2
input
7 6 5
H 4
V 3
V 5
H 2
V 1
output
28
16
12
6
4
Note
Picture for the first sample test:
Picture for the second sample test:


--------------------------------------------------------------------------------------------------------------------------------------------
At any moment we realise that the maximum area is the product of the segment produced my max vertical length and maximum height 
We keep 4 sets that represent the following (1) Cuts at horizontal (2) Cuts at vertical (3) Length of vetical segments (4) width of horizontal segment initiall we push (0,w) to height and (0,h) to vertical then we push h to horizontal size array and w to vertical size array now when we make a cut horizontally clearly imagine the things taking place Suppose we cut at dist d (1) we try to find the position of the cut between to last cuts(initially it is between 0 and h) (2) we remove the piece (h-0) from the set that represents horizontal cut lengths(segments) (3) We insert two new segment of length (d1-0) & (h-d1) to the segments. Thus we see we are simulating the process taking place . The maximum are can be found by product of maximum horizontal length and maximum vertical length




---------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include<bits/stdc++.h> using namespace std; #define ll long long int int main() { int n; int w,h; cin>>w>>h>>n; multiset<int> cuth,cutw,maxh,maxw; cuth.insert(0); cuth.insert(h); cutw.insert(0); cutw.insert(w); maxh.insert(h); maxw.insert(w); int len; for(int i=0;i<n;i++) { char str[10]; cin>>str; cin>>len; if(str[0]=='H') { // cout<<"t 1 "<<endl; multiset<int>:: iterator it,it1,it2; it=cuth.lower_bound(len); // cout<<*it<<endl; it1=it; it1--; int val=*it-*it1; // cout<<"del "<<val<<endl; it2=maxh.lower_bound(val); maxh.erase(it2); cuth.insert(len); maxh.insert((len-*it1)); maxh.insert((*it-len)); } else { multiset<int>:: iterator it,it1,it2; it=cutw.lower_bound(len); it1=it; it1--; int val=*it-*it1; // cout<<"del val "<<val<<endl; it2=maxw.lower_bound(val); maxw.erase(it2); cutw.insert(len); maxw.insert((len-*it1)); maxw.insert((*it-len)); } //cout<<"done "<<endl; ll l1=*(maxw.rbegin()); ll l2=*(maxh.rbegin()); //cout<<l1<<" "<<l2<<endl; ll ans=l1*l2; cout<<ans<<endl; } return 0; }

Points on Line

 Points on Line
Little Petya likes points a lot. Recently his mom has presented him n points lying on the line OX. Now Petya is wondering in how many ways he can choose three distinct points so that the distance between the two farthest of them doesn't exceed d.
Note that the order of the points inside the group of three chosen points doesn't matter.
Input
The first line contains two integers: n and d (1 ≤ n ≤ 105; 1 ≤ d ≤ 109). The next line contains n integers x1, x2, ..., xn, their absolute value doesn't exceed 109 — the x-coordinates of the points that Petya has got.
It is guaranteed that the coordinates of the points in the input strictly increase.
Output
Print a single integer — the number of groups of three points, where the distance between two farthest points doesn't exceed d.
Please do not use the %lld specifier to read or write 64-bit integers in ะก++. It is preferred to use the cincout streams or the %I64dspecifier.
Sample test(s)
input
4 3
1 2 3 4
output
4
input
4 2
-3 -2 -1 0
output
2
input
5 19
1 10 20 30 50
output
1
Note
In the first sample any group of three points meets our conditions.
In the seconds sample only 2 groups of three points meet our conditions: {-3, -2, -1} and {-2, -1, 0}.
In the third sample only one group does: {1, 10, 20}.

--------------------------------------------------------editorial----------------------------------------------------------------
Let's select the rightmost point of our triplet. In order to do this we can iterate over all points in ascending order of their X-coordinate. At the same time we'll maintain a pointer to the leftmost point which lays on the distance not greater than d from the current rightmost point. We can easily find out the number of points in the segment between two pointers, excluding the rightmost point. Let's call this number k. Then there exist exactly k * (k - 1) / 2 triplets of points with the fixed rightmost point. The only thing left is to sum up these values for all rightmost points.

----------------------------------------------------code------------------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
typedef long int li;


 vector<lli> v;
  lli ans=0;
  
int main()
{
int n,d;
 cin>>n>>d;
 for(int i=0;i<n;i++)
  {
  lli a;
   cin>>a;
   v.push_back(a);
  }
  sort(v.begin(),v.end());
  for(int i=0;i<n-2;i++)
   {
    // cout<<" i "<<i<<endl;
        lli maxi;
    lli pre=v[i];
    // if(pre <0)
      maxi=pre+d;
       vector<lli> :: iterator it;
       it=upper_bound(v.begin()+i+2,v.end(),maxi);
       if(it==v.end() || *it-d>v[i]) it--;
      lli sets=it-v.begin()-i;
       // cout<<sets<<endl;
       ans+=(sets*(sets-1))/2;
      //  cout<<ans<<endl;
     
}
  
cout<<ans<<endl;
}

Friday, 25 September 2015

Little Ashish's Huge Donation

Little Ashish's Huge Donation
https://www.hackerrank.com/challenges/little-chammys-huge-donation

Problem Statement
Little Ashish is doing internship at multiple places. Instead of giving parties to his friends he decided to donate candies to children. He likes solving puzzles and playing games. Hence he plays a small game. Suppose there are N children. The rules of the game are:
  1. The ith child gets i2 candies (1iN).
  2. The yth child cannot get a candy until and unless all the children before him (1i<y) gets candies according to rule number 1.
One of his jealous friends, Pipi, asks him "Given X (the number of candies) how many children will you be able to serve?". Little Ashish fears calculations and cannot solve this problem so he leaves this problem to the worthy programmers of the world. Help little Ashish in finding the solution.
Input Format 
The first line contains T i.e. number of test cases. 
T lines follow, each line containing an integer X.
Output Format 
For each testcase, print the output that little Ashish wants in one line.
Constraints 
1T10000 
1X1016
Note: If the ith child doesn't get i2 number of candies then it's not counted as a successful donation
Sample Input
3
1
5
13
Sample Output
1  
2  
2  
Explanation
  1. For X=1. Only the 1st child can get the candy (i.e. 12 candy) and no other child.
  2. For X=5. Both the 1st(12 candies) and the 2nd(22 candies) children can get the candies.
  3. For X=13. Since the 3rd child will get only 8 candies following the rule it won't be counted as a successful donation. Only the 1st and the 2nd children can get 1 and 4 candies respectively.
-------------------------------------EDITORIAL-----------------------------

The binary search approach


Consider a list of integers `[S1,S2,S3,]` where:

`Si` = Total number of candies donated by Little Ashish till the `ith` child.

This list consists of numbers in increasing order.

Now, we want to find the maximum number of children `n` that we can serve; in other words, the largest integer `n` such that `SnX`.

Whenever we have a collection (list) which is either in increasing or decreasing order, we can applybinary search to find the numbers which are equal to, greater than, or less than a given number.

The only thing thing that remains is figuring out the details. Look at the following code snippet to get a better idea of the approach (also recommended is checking the setter's code):
def answer(X):
    L = 1
    R = 1000000 # a really large number which should be 
                # much greater than the actual answer, i.e.
                # S(R) > X

    while R - L > 1:
        M = (L + R)/2
        if S(M) <= X:
            L = M
        else:
            R = M

    return L
Note that this function assumes you have already implemented the function S(i) which should return the value `Si` quickly.

Addendum: Formula for `Si`


Let us try to find a formula for `Si`. Since the `ith` child requires `i2` candies, we have:
`
Si=12+22+32++i2
` These are well known of numbers known as the square pyramidal numbers, and one can derive a formula for `Si` using the following manipulations:
`
(i+1)3(i+1)3(i+1)3(i+1)3(i+1)33Si=j=0i[(j+1)3j3] (Telescoping series)=j=0i[j3+3j2+3j+1j3]=j=0i[3j2+3j+1]=3j=0ij2+3j=0ij+j=0i1=3Si+3j=0ij+(i+1)=(i+1)33j=0ij(i+1)
`
Now, the number `Ti=ij=0j=0+1+2++i` is called a triangular number whose formula can be derived as:
`
TiTi2Ti2TiTi=1++i=i++1=(i+1)++(i+1)=i(i+1)=i(i+1)2
`
Back to `Si`:
`
3Si3Si3Si3Si3Si3Si3SiSi=(i+1)33j=0ij(i+1)=(i+1)33Ti(i+1)=(i+1)33i(i+1)2(i+1)=(i+1)[(i+1)23i21]=(i+1)[i2+2i+13i21]=(i+1)[i2+i2]=i(i+1)2[2i+1]=i(i+1)(2i+1)6
`
Therefore, `Si` is just `i(i+1)(2i+1)6`.

Addendum: Newton's method


We'll describe a faster, more advanced approach which we hope you'll find helpful.

Note that we are finding the largest `n` such that `S(n)X`. Now, since `n` is the largest such integer, we have `S(n+1)>X`. Therefore, the largest real solution `r` of the equation `S(x)=X` is in the interval `[n,n+1)`, and since `nr<n+1`, we have `n=r`. Therefore, one approach is simply to find the largest real root `r` or the equation `r(r+1)(2r+1)6=X`, and taking the answer as `n=r` :) You can use your favorite solution-finding method for this. In this section, we'll useNewton's method.

We want to find a solution x of the equation `S(x)=X`. Since, `S(x)=x(x+1)(2x+1)6`, we can rewrite this equation as `x(x+1)(2x+1)6X=0`, so we are now finding a root of the polynomial `f(x)=x(x+1)(2x+1)6X`. Newton's method is an iterative method that starts with an initial guess `x0`, and updating it using the following rule:
`
xi+1=xif(xi)f(xi)
`
where `f` is the derivative of `f`. One does this iteration until the `xi` converges.

Now, the derivative of `f(x)=2x3+3x2+x6X` is `f(x)=6x2+6x+1=6x(x+1)+1`. Therefore, our update rule is the following:
`
xi+1=xixi(xi+1)(2xi+1)6X6xi(xi+1)+1
`
and finally, `f(x)2x36X`, so a good initial guess would be `x0=3X3`.

All of this is implemented in the following code snippet:
def answer(X):
    r = pow(3*X, 1/3.) # approximate solution
    while True:
        nr = r - (r*(r+1)*(2*r+1) - 6*X)/(6*r*(r+1) + 1)
        if abs(r - nr) < 1e-6: # converged
            return int(nr)
        r = nr

------------------------------EDITORIAL------------------------------------

#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define test()    int test_case;cin>>test_case;while(test_case--)
#define fr(i,n) for(int i=0;i<n;i++)
#define frr(i,a,n) for(int p=i;p<n;p++)
#define sll(a) scanf("%lld",&a)
#define sl(a) scanf("%ld",&a)
#define si(a) scanf("%i",&a)
#define sd(a)  scanf("%ld",&a)
#define sf(a) scanf("%f",&a)
#define rn(a) return a
#define pai pair<int,int>
#define pal pair<li,li>
#define pall pair<lli,lli>
#define ff first
#define ss second
#define mod  1000000007
#define mp make_pair
#define pb push_back
#define pll(a) printf("%lld\n",a);
#define pl(a) printf("%lld\n",a);
#define pi(a) printf("%d\n",a);
#define pd(a) printf("%lf\n",a);
#define pf(a) printf("%f\n",a);
lli ans=0;
list<lli> li[1000];
lli visited[10000];
lli func(lli num)
 {
  return (num*(num+1)*(2*num+1))/6;
 }
 int main()
  {
  test()
   {
    lli x;
    lli ans=0;
    cin>>x;
     lli mini=1;
      lli maxi=1000000;
       while(mini<maxi)
        {
        lli mid=(mini+maxi)/2;
        
         if(func(mid)>x)
          {
          maxi=mid;
}
else
{
ans=max(ans,mid);
mini=mid+1;
}
}
 
 cout<<ans<<endl;
 
}
return 0;
  }