Friday, 25 September 2015

Manager of HackerX company is having big trouble. Workers are very unhappy with the way salary is given to them. They want every worker to have the same salary, otherwise they will go on a strike.
Their current salaries are denoted by a sequence of N integers: A1, A2, A3 ... AN . Manager has decided to take action and make their salaries equal. He uses the following process until all salaries are equal. This method is called normalization:
a) Select any two different values from A.
b) Replace larger value with the difference of the two. Difference of two positive integers Band C is defined as |B-C|.
He knows that the final value will always be unique. 
Now, Q queries are given. In each query you are given an integer KK is the amount to be added to everyone's salary as bonus, before the normalization.
Input Format 
First line contains, N and Q, the number of employees and the number of queries. Next line contains N space seperated positive integers denoting the array A. Next Q lines contain queries. Each query consists of one integer per line denoting K.
Output Format 
For each query, print the normalized salary (which is same for everyone in the end) in one line.
Constraints 
1 ≤ N ≤ 105 
1 ≤ Q ≤ 105 
1 ≤ A[i] ≤ 1014 
0 ≤ K ≤ 109
Sample Input
4 2
9 12 3 6
0
3
Sample Output
3
3
Explanation 
for sample input: 
If 0 is added to every element of array A, it will remain same. 
One way to normalise A is this: 
1. Picking 12 and 3 gives: 9 9 3 6 
2. Picking 3 and 6 gives: 9 9 3 3 
3. Picking 9 and 3 gives: 6 9 3 3 
4. Picking 9 and 3 gives: 6 6 3 3 
5. Picking 6 and 3 gives: 3 6 3 3 
6. Picking 6 and 3 gives: 3 3 3 3
For the salaries A1, A2, ..., An (assume sorted), the answer is gcd(A1, A2, ..., An).
If we add K to all, the answer is: gcd(A1+K, A2+K, A3+K, ..., An+K)
= gcd(A1+K, A2+K-(A1+K), A3+K-(A1+K)..., An+K-(A1+K))
= gcd(A1+K, A2 - A1, A3 - A1..., An-A1)
= gcd(A1+K, G)
where G = gcd(A2 - A1, A3-A1..., An-A1) (precalculated).


#include<bits/stdc++.h>
using namespace std;
struct _ { ios_base::Init i; _() { cin.sync_with_stdio(0); cin.tie(0); } } _;

const int N = 100006;
long long a[N];

long long gcd(long long a, long long b)
{
    if(a < 0) a = -a; if(b < 0) b = -b;
    return b ? gcd(b, a % b) : a;
}

int main()
{
    int n, q; cin >> n >> q;
    long long temp;
    assert (n<=100000 && n>=1 && q<=100000 && q>=1);
    for(int i = 0; i < n; ++i) {
      cin >> temp;
      assert (temp<=100000000000000L && temp>=0);
      a[i] = temp;
    }

    long long d = 0;
    for(int i = 0; i < n; ++i)
        d = gcd(d, a[i] - a[1]);

    while(q--)
    {
        int k; cin >> k;
        assert (k>=0 && k<=1000000000);
        cout << gcd(d, a[0] + k) << '\n';
    }
    return 0;
}

Thursday, 24 September 2015

To strengthen the concept of DP+bitmasks


SPOJ(6072. Chocolate)

Chocolate is a problem from the world final ACM-ICPC 2010. You can see the text here

My solution:
                    Well first we can see that the n <= 15 and x,y <= 100, There is 2^n way of get a subset of the all pieces.
                      
                   For example:
                         n =  4;
                         pieces:6,3,2,1;
In the binary representation of the mark a 0 meant that don't take this piece and a 1 that take this piece.
                  
                             
 mask (from 0 to 2^4) binary representation Piece Sum of piece
 0 0000 {} 0
 1 0001 {1} 1
 2 0010 {2} 2
 3 0011 {2,1} 3
 4 0100 {3} 3
 5 0101 {3,1} 4
 6 0110 {3,2} 5
 7 0111 {3,2,1} 6
 8 1000 {6} 6
 9 1001 {6,1} 7
 10 1010 {6,2} 8
 11 1011 {6,2,1} 9
 12 1100 {6,3} 9
 13 1101 {6,3,1} 10
 14 1110 {6,3,2} 11
 15 1111 {6,3,2,1} 12

 We can do a function that take a mask ,x ,y and return true or false if with the piece of this mask we can get a rectangle of (x,y)

bool Solve(int mask , int x , int y)
{
       if(Sum[mask]!= x*y) return false;
        
       if(ActivePieces(mask)==1) return true;       

       foreach(sub)//that sub is a subset of mask mean that all bit that is 1 in sub have to be 1 in mask and mask > sub
       {
           sub1 = mask - sub;
           //now we can to break the chocolate of (x,y), for can break it parallel to X, y have to divide to Sum[sub] and Sum[sub1].
          if(Sum[sub]%y == 0  and  Sum[sub1]%y == 0)
            {
                    if(Solve(sub,Sum[sub]/y,y) and Solve(sub1,Sum[sub1]/y,y))
                         return true;
            }
          // now the same parallel to Y
           if(Sum[sub]%x == 0  and  Sum[sub1]%x == 0)
            {
                    if(Solve(sub,Sum[sub]/x,x) and Solve(sub1,Sum[sub1]/x,x))
                         return true;
            }
       }
     return false;
}

Now see that we can to have 2^n*x*y state. for the max number of that can be 327680000 so it is big but we can notice that x or y are linked.If I have the mask and x I can calculate the y so we have only 3276800. so my idea for save is (mask,max(x,y)) and I can use memorization for do it faster.

The other problem is:
      How can I do the cycle of sub ??
      if you have this problem you have to see this tutorial from topcoder.      

My Code:
                
  • bool DP(int mask, int x , int y)
  • {
  • if(x > y)
  • x^=y^=x^=y;
  •  
  • if(S[mask]!=x*y)
  • return false;
  •  
  • if((mask & (mask-1)) == 0)
  • return true;
  •  
  • if(Y[mask][y])
  • return M[mask][y];
  •  
  • Y[mask][y] = 1;
  •  
  •  
  • for(int mask1 =((mask-1)& mask);mask1;mask1 = ((mask1-1) & mask)){
  • if((S[mask1] % x == 0) && DP(mask1,x,S[mask1]/x) && DP(mask-mask1,x,S[mask-mask1]/x))
  • {
  • M[mask][y] = 1;
  • return 1;
  • }
  • if((S[mask1] % y == 0) && DP(mask1,y,S[mask1]/y) && DP(mask-mask1,y,S[mask-mask1]/y))
  • {
  • M[mask][y] = 1;
  • return 1;
  • }
  • }
  • M[mask][y] = 0;
  • return 0;
  • }
  •                 
    A brief note on de arrangements



    proof from inclusion exclusion principle and other associated proofs will help to enhance the knowledge.

    http://math.stackexchange.com/questions/83380/i-have-a-problem-understanding-the-proof-of-rencontres-numbers-derangements/83472#83472

     link 1

    http://math.stackexchange.com/questions/507019/derangement-of-n-elements



    Read this articles thouroughly

    Question

    Professor just has checked all the N students tests. Everything was fine but then he realised that none of the students had signed their papers, so he doesn't know which test belongs to which student.
    But it's definitely not professors's job to catch every student and asked him to find his paper! So he will hand out these papers in a random way.
    Now he is interested in the following question: what is the probability that X students will receive someone other's test, not their where L <= X <= R.
    Input:
    The first line contains 3 space-separated integers: N, L, R.
    Output:
    Let's suppose the answer is a fraction P / Q where P and Q are coprime. Output P * Q-1 modulo 109 + 7.
    Constraints:
    1 ≤ N ≤ 100
    0 ≤ L ≤ R ≤ N


    Notice the number of dearangements of k objects can be recursively shown as 

          D(n)= (n-1)  [  D(n-1) + D(n-2)]  using this recurrence we first build the table and then its a simple 
    combinatorics question.



    Solution



    #include<iostream>
    #include<bits/stdc++.h>
    #define mod 1000000007
    #define ll long long int 
    ll fact[110];
    ll factinv[110];
    ll C[120][120];
    ll dearange[110];
    void ncr(int n)
    {
    int i,j;
    for(i=0;i<=n;i++)
        {
            for(j=0;j<=i;j++)
            {
                if(i == j || j == 0)
                    C[i][j] = 1;
                else
                    C[i][j] = (C[i-1][j] + C[i-1][j-1])%mod;
            }
        }
    }
    void calcdearange(int n)
    {
    dearange[0] = 1;
        dearange[1] = 0;
        for(int i=2;i<=n;i++)
        {
            dearange[i] = ((i-1)*(dearange[i-1]+dearange[i-2]))%mod;
        }
    }
    ll bigpow(ll a,ll m)
    {
     if(m==0)
     return 1;
     ll temp=bigpow(a,m/2);
     if(m&1)
     return (((temp*temp)%mod)*a)%mod;
     return (temp*temp)%mod;
    }
    ll invmod(ll num,ll m)
    {
    ll val=bigpow(num,m-2);
    return val;
    }
    void prefact()
    {
     fact[0]=1;
     for(int i=1;i<=101;i++)
     fact[i]=(i*fact[i-1])%mod;
    }

    using namespace std;
    int main()
    {
    ncr(110);
    calcdearange(102);
    prefact();
    //cout<<invmod(6,mod)<<endl;;
    int n;
    cin>>n;
    int l,r;
    cin>>l>>r;
    ll ways=0;
    for(int i=l;i<=r;i++)
    {
    ll temp=(C[n][i]*dearange[i])%mod;
    ways=(ways+temp)%mod;
    }
    //cout<<ways<<endl;
    //cout<<fact[n]<<endl;

    ll den=invmod(fact[n],mod);
    // cout<<den<<endl;
    ll ans=(den*ways)%mod;
    cout<<ans<<endl;
    return 0;
    }

    Saturday, 19 September 2015

    Launch Tower 
    Solved

    Problem code: ACM14AM3

    All submissions for this problem are available.

    "The Mars Orbiter Mission probe lifted-off from the First Launch Pad at Satish Dhawan Space Centre (Sriharikota Range SHAR), Andhra Pradesh, using a Polar Satellite Launch Vehicle (PSLV) rocket C25 at 09:08 UTC (14:38 IST) on 5 November 2013".
    The secret behind this successful launch was the launch pad that ISRO used. An important part of the launch pad is the launch tower. It is the long vertical structure which supports the rocket.
    ISRO now wants to build a better launch pad for their next mission. For this, ISRO has acquired a long steel bar, and the launch tower can be made by cutting a segment from the bar. As part of saving the cost, the bar they have acquired is not homogeneous.
    The bar is made up of several blocks, where the ith block has durability S[i], which is a number between 0 and 9. A segment is defined as any contiguous group of one or more blocks.
    If they cut out a segment of the bar from ith block to jth block (i<=j), then the durability of the resultant segment is given by ( S[i]*10(j-i) + S[i+1]*10(j-i-1) + S[i+2]*10(j-i-2) + … + S[j] * 10(0) ) % M.
    In other words, if W(i,j) is the base-10 number formed by concatenating the digits S[i], S[i+1], S[i+2], …, S[j], then the durability of the segment (i,j) is W(i,j) % M.
    For technical reasons that ISRO will not disclose, the durability of the segment used for building the launch tower should be exactly L. Given S and M, find the number of ways ISRO can cut out a segment from the steel bar whose durability is L.

    Input

    The first line contains a string S. The ith character of this string represents the durability of ith segment.
    The next line contains a single integer Q, denoting the number of queries.
    Each of the next Q lines contain two space separated integers, denoting M and L.

    Output

    For each query, output the number of ways of cutting the bar on a separate line.

    Constraints

    • 1 ≤ |S| ≤ 2 * 10^4
    • Q ≤ 5
    • 0 < M < 500
    • 0 ≤ L < M

    Example

    Input:
    23128765
    3
    7 2
    9 3
    15 5
    
    Output:
    9
    4
    5
    

    Explanation

    For M=9, L=3, the substrings whose remainder is 3 when divided by 9 are: 3, 31287, 12 and 876.


    This is a very important and basic questions concerning DP with remainders. Consider this    thing
    (a*b*c)%m = a%m+b%m+C%m
    Now  suppose we are at a position where our string is 256 and we have to find the mod of that with  7
    Now we can  till i-1 that is till 5 we had two mods one for 5 which is equal to 5 and another for 25 which is equal to 4 . Now the new mod value can be calulated (5*10+6)%7 for 56 and (4*10+6)%7 for 256 which are equal to 0 and 4 indeed we see when we divide 56 by 7 we get remainder as 0 and 256 by 7 we get remainder as  4. This can be computed in a dp 

     see the code for clarification

    #include<bits/stdc++.h>
    using namespace std;
    char str[100010];
    int dp[20010][510];
    int main()
    {
    cin>>str;
    int l=strlen(str);
    int q;
    cin>>q;
    while(q--)
    {
    int m,r;
    cin>>m>>r;
    for(int i=0;i<l+2;i++)
    {
    for(int j=0;j<m+2;j++)
    dp[i][j]=0;
    }
    dp[0][(str[0]-'0')%m]++;
    for(int i=1;i<l;i++)
    {
    //cout<<"for  i "<<i<<endl;
    dp[i][(str[i]-'0')%m]++;
    for(int j=0;j<m;j++)
    {
          // int val=dp[i-1][j];
    dp[i][(j*10+(str[i]-'0'))%m]+=dp[i-1][j];
    // cout<<"increasing"<<(j*10+(str[i]-'0'))%m<<" by  "<<dp[i-1][j]<<endl;
    }
    }
    int sum=0;
    for(int i=0;i<l;i++)
    {
    sum+=dp[i][r];
    }
    //cout<<dp[l-1][r]<<endl;
    cout<<sum<<endl;
    }
    return 0;
    }
    Problem Statement
    Delhi metro has n stations connected by roads between them. The underlying network of roads between the stations has a tree structure. For each road u,v, there is a fare for going from station u to station v.
    Devu wants to travel by metro, so he is currently at station 1. In a single step, he can uniformly randomly go to any of the neighbouring stations of the current station.
    The metro charges you based on the starting and ending station regardless of the actual distance you might have travelled. So the fare charged from you for a journey will be the total fare of roads on the path from start to end station.
    Find out the expected fare of his journey having a total of k steps.
    Input Format
    • The first line contains an integer T, that is the number of test cases.
    • For each test case
      • The first line contains two space-separated integers, n,k, as defined in the problem statement.
      • In the next n1 lines, each line contains three space-separted integers u,v,wdenoting that there is a road between station u to v with fare equal to w.
    Output Format
    For each test case, print a real number having absolute or relative error of 1e-6.
    Constraints
    • 1T50
    • 2n,k50
    • 1w109
    • 1u,vn
    • It is guaranteed that there is no multi-edge and self-loop in the given input.
    Sample Input
    2
    2 1
    1 2 4
    2 2
    1 2 4
    
    Sample Output
    4.000000
    0.000000
    
    Explanation
    • In the first example, you can only go station 2 from station 1 in a single step. So the fare charged from you will be 4.
    • In the second example, you can go from station 1 to station 1 again in two steps. So the fare charged from you is zero.

    This can be done with a 2D dp where the state is dp[i][j] meaning going to ith node at jth step.

    We observe that dp[1][0]=1.00 as initially we start with 1.

    The we go for an o(n^3) solution which tries go traverse at ith node from kth node and the probability of doing such is 1/number of edges.


    code here

    #include<bits/stdc++.h>
    using namespace std;
    long long int dist[70];
    bool vis[70];
    double dp[60][60];
    bool connect[60][60];
    #define mp make_pair
    #define pb push_back
    #define ff first
    #define ss second
    int cnt[60];
    void fill(int st,list<pair<int,int> >arr[])
    {
    vis[st]=1;
    dist[st]=0;
    stack<int> s;
    s.push(st);
    while(!s.empty())
    {
       int a=s.top();
       s.pop();
        list<pair<int,int> > ::iterator it;
       for(it=arr[a].begin();it!=arr[a].end();it++)
       {
        if(!vis[it->ff])
        {
        vis[it->ff]=1;
        dist[it->ff]=dist[a]+it->ss;
        s.push(it->ff);
         }
        }
    }
    }
    int main()
    {
    int t;
    // freopen("ans.txt","w",stdout);
    cin>>t;
    while(t--)
    {int n,a,b,w;
    cin>>n;
    int k;
    cin>>k;
    list<pair<int,int> >arr[100];
    memset(cnt,0,sizeof(cnt));
    memset(connect,0,sizeof(connect));
    for(int i=0;i<n-1;i++)
    {
    cin>>a>>b>>w;
    cnt[a]++;
    cnt[b]++;
    arr[a].pb(mp(b,w));
    arr[b].pb(mp(a,w));
    connect[a][b]=1;
    connect[b][a]=1;
    }
    memset(vis,0,sizeof(vis));
    fill(1,arr);
    /*for(int i=1;i<=n;i++)
    {
    cout<<dist[i]<<" ";
    }
    cout<<endl;*/
    dp[1][0]=1.00;
    for(int i=1;i<=n+2;i++)
    {
    for(int t=1;t<=k+2;t++ )
    dp[i][t]=0.00;
    }
    dp[1][0]=1.00;
    for(int i=1;i<=k;i++)
    {
     for(int nodes=1;nodes<=n;nodes++)
     {
      for(int from=1;from<=n;from++)
      {
                 double p=(double)cnt[from];
        if(from!=nodes && connect[from][nodes]==1)
        {
             dp[nodes][i]+=(dp[from][i-1])/p;
         }
    }
     }
    }
    double ans=0.00;
    for(int i=1;i<=n;i++)
    {
      double dt=(double)(dist[i]-dist[1]);
      ans+=dt*dp[i][k];
    }
    printf("%.12lf\n",ans);
    }
    return 0;
    }