Facing problem in spoj RACETIME — Race Against Time

Revision en1, by adamantium, 2016-06-03 20:21:42

I tried this problem with segment tree first and got TLE. Then I used square-root but again got TLE. To solve the problem with square-root i used tree which size is sqrt(n) * sqrt(n), where n is the size of the array. In every block of the tree I kept sqrt(n) elements of the array sorted in ascending order. When update occur I push the element in a block where it's index remain and again sort this block. And when i got query operation for every block which is in the range I found how many elements are less than the given value. This can be done with binary search for every block. Please tell me where i should optimize my code. Here you can have a look at my code.

/////////////////////// All Is Well /////////////////////////

#include <bits/stdc++.h>

#define FOR(i, s, e) for(int i=s; i<e; i++)
#define loop(i, n) for(int i=0; i<n; i++)
#define CIN   ios_base::sync_with_stdio(0); cin.tie(0)
#define getint(n) scanf("%d", &n)
#define pb(a) push_back(a)
#define ll long long int
#define ull unsigned long long int
#define dd double
#define SZ(a) int(a.size())
#define read() freopen("input.txt", "r", stdin)
#define write() freopen("output.txt", "w", stdout)
#define mem(a, v) memset(a, v, sizeof(a))
#define all(v) v.begin(), v.end()
#define pi acos(-1.0)
#define pf printf
#define sf scanf
#define mp make_pair
#define paii pair<int, int>
#define padd pair<dd, dd>
#define pall pair<ll, ll>
#define fr first
#define sc second
#define CASE(n) printf("Case %d: ",++n)
#define CASE_COUT cout<<"Case "<<++cas<<": "
#define inf 1000000000
#define EPS 1e-9

using namespace std;

//8 way moves
//int fx[]={0,0,1,-1,1,1,-1,-1};
//int fy[]={1,-1,0,0,1,-1,1,-1};

//knight moves
//int fx[]={-2,-2,-1,-1,1,1,2,2};
//int fy[]={-1,1,-2,2,-2,2,-1,1};

//Bit operation
int SET(int n,int pos)
{
    return n=n | (1<<pos);
}
int RESET(int n,int pos)
{
    return n=n & ~(1<<pos);
}
int CHECK(int n,int pos)
{
    return (bool) (n & (1<<pos));
}


int bigMod(int n,int power,int MOD)
{
    if(power==0)
        return 1;
    if(power%2==0)
    {
        int ret=bigMod(n,power/2,MOD);
        return ((ret%MOD)*(ret%MOD))%MOD;
    }
    else return ((n%MOD)*(bigMod(n,power-1,MOD)%MOD))%MOD;
}

int modInverse(int n,int MOD)
{
    return bigMod(n,MOD-2,MOD);
}

int POW(int x, int y)
{
    int res= 1;
    for ( ; y ; )
    {
        if ( (y&1) )
        {
            res*= x;
        }
        x*=x;
        y>>=1;
    }
    return res;
}

int inverse(int x)
{
    dd p=((dd)1.0)/x;
    return (p)+EPS;
}

int gcd(int a, int b)
{
    while(b) b^=a^=b^=a%=b;
    return a;
}

int nC2(int n)
{
    return n*(n-1)/2;
}

int MOD(int n,int mod)
{
    if(n>=0)
        return n%mod;
    else if(-n==mod)
        return 0;
    else
        return mod+(n%mod);
}

const int mx=100005;

int data[mx];

vector< paii >tree[350];


int getid(int i,int blck)
{
    return i/blck;
}

void init(int blck,int n)
{
    int cnt=0;
    for(int i=0; i<=blck; i++)
    {
        int p=0;
        for(int j=0; j<blck; j++)
        {
            if(cnt>=n)
                break;
            tree[i].pb(mp(data[cnt],cnt));
            cnt++;
            p++;
        }
        if(p)
            sort(all(tree[i]));
    }
}

void update(int ind,int x,int blck)
{
    int blckid=getid(ind,blck);
    for(int i=0; i<tree[blckid].size(); i++)
    {
        if(tree[blckid][i].sc==ind)
        {
            tree[blckid][i].fr=x;
            break;
        }
    }
    sort(all(tree[blckid]));
}

int BS(int left,int right,int x,int blckid)
{
    int mid=(left+right)/2;
    int ans=right;
    while(left<=right)
    {
        if(tree[blckid][mid].fr<x)
        {
            left=mid+1;
        }
        else
        {
            right=mid-1;
            ans=mid;
        }
    }
    return ans;
}

int query(int left,int right,int x,int blck)
{
    int leftid=getid(left,blck);
    int rightid=getid(right,blck);
    if(leftid==rightid)
    {
        int cnt=0;
        for(int i=0; i<tree[leftid].size(); i++)
        {
            if(tree[leftid][i].sc>=left && tree[rightid][i].sc<=right && tree[leftid][i].fr<=x)
                cnt++;
        }
        return cnt;
    }
    if(leftid+1==rightid)
    {
        int cnt=0;
        for(int i=0; i<tree[leftid].size(); i++)
        {
            if(tree[leftid][i].sc>=left &&  tree[leftid][i].fr<=x)
                cnt++;
        }
        for(int i=0; i<tree[rightid].size(); i++)
        {
            if(tree[rightid][i].sc<=right && tree[rightid][i].fr<=x)
                cnt++;
        }
        return cnt;
    }
    int cnt=0;
    for(int i=0; i<tree[leftid].size(); i++)
    {
        if(tree[leftid][i].sc>=left && tree[leftid][i].fr<=x)
            cnt++;
    }

    for(int i=leftid+1;i<rightid;i++)
    {
        int pp=BS(0,blck-1,x,i);
        if(tree[i][pp].fr==x || pp==blck-1)
            pp++;
        cnt+=pp;
    }

    for(int i=0; i<tree[rightid].size(); i++)
    {
        if( tree[rightid][i].sc<=right && tree[rightid][i].fr<=x)
            cnt++;
    }
    return cnt;
}

int main()
{
    int t,cas=0;
    int n,q;
    sf("%d %d",&n,&q);
    int blck=sqrt(n);
    loop(i,n)
    {
        getint(data[i]);
    }

    init(blck,n);
//    for(int i=0;i<blck;i++)
//    {
//        for(int j=0;j<tree[i].size();j++)
//            cout<<tree[i][j].fr<<" ";
//        cout<<endl;
//    }
    while(q--)
    {
        getchar();
        char cc;
        int p,qq,x;
        sf("%c",&cc);
        if(cc=='M')
        {
            sf("%d %d",&p,&x);
            update(p-1,x,blck);
        }
        else
        {
            sf("%d %d %d",&p,&qq,&x);
            pf("%d\n",query(p-1,qq-1,x,blck));
        }
    }

    return  0;

}

Tags square root, data structure, binary search, spoj

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en2 English adamantium 2016-06-03 20:23:51 5288
en1 English adamantium 2016-06-03 20:21:42 6070 Initial revision (published)