Accounting | Trading | Tools | Accounts | Login
Kurniady Systems - Tools
 
Tuesday, 07 September 2010 - 17:07:30
Home | About

Viewing Text Document

Title:

INC 2008 Final F

Owner: Andrian Kurniady

Last updated on: Tuesday, 15 July 2008

Description:

My solution for INC 2008 final problem F. Still got Time Limit Exceeded.

Content:

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
int delt[101000];
int isi[101000][6];

char buffer[500];

typedef struct Node {
    int x;
    int baka;
    int count;
    int min, max;
    Node* left, *right;
} Node;

Node preReserve[1000000];
int upc;

inline Node* make_Node(int x){
    Node* temp = preReserve+upc;
    upc++;
    
    temp->baka = 1;
    temp->count = 1;
    temp->x = x;
    temp->left = NULL;
    temp->right = NULL;    
    temp->min = x;
    temp->max = x;
    return temp;
}
void insert(Node* pos, int x){
    pos->max>?=x;
    pos->min<?=x;
    
    if (pos->x==x){
        pos->baka++;
        pos->count++;
    } else if (pos->x>x){
        // kiri
        if (pos->left!=NULL){
            pos->baka++;
            insert(pos->left, x);
        } else {
            pos->baka++;
            pos->left = make_Node(x);
        }
    } else {
        // kanan
        if (pos->right!=NULL){
            pos->baka++;
            insert(pos->right, x);
        } else {
            pos->baka++;
            pos->right = make_Node(x);
        }        
    }
}
int countBetween(Node* pos, int a, int b, int kiripol, int kananpol){
    if (pos==NULL) return 0;
    
    back:
    
    if (kiripol && kananpol)
        return pos->baka;
        
    if (pos->min>b || pos->max<a) return 0;
    
    int x = pos->x;
    if (kiripol){
        if (pos->max<=b){
            return pos->baka;
        } else {
            if (b<x){
                return countBetween(pos->left, a,b,1, 0);
            } else if (b==x){
                return pos->left->baka + (pos->count);
            } else {
                // b > x
                return pos->left->baka +(pos->count)+countBetween(pos->right, a,b,1,0);
            }
        }
    } else if (kananpol){
        if (pos->min>=a){
            return pos->baka;
        } else {
            if (a>x){
                return countBetween(pos->right, a,b,0,1);
            } else if (a==x){
                return pos->right->baka+(pos->count);
            } else {
                return pos->right->baka+(pos->count)+countBetween(pos->left, a,b,0,1);
            }
        }
    } else {
        if (x>=a && x<=b){
            int res = pos->count;
            if (a<x){
                res+=countBetween(pos->left, a,b,0,1);
            } 
            if (b>x){
                res+=countBetween(pos->right, a,b,1,0);
            }
            return res;
        } else {
            if (b<x){
                pos = pos->left;
                goto back;
//                return countBetween(pos->left, a,b,0,0);
            } else {
                pos = pos->right;
                goto back;
  //              return countBetween(pos->right,a ,b,0,0);
            }
        }        
    }
}
void buang(Node* pos, int x){
    pos->baka--;
    
    if (pos->x==x){
        pos->count--;     
    } else if (pos->x>x){
        buang(pos->left, x);
    } else {
        buang(pos->right,x);
    }
}
void bantai(Node* lala){
    if (lala!=NULL){
        bantai(lala->left);
        bantai(lala->right);
        delete(lala);
    }
}

int main(){
    int ntc;
    scanf("%d", &ntc);
    for (int ttc=1;ttc<=ntc;ttc++){
        upc = 0;
        long long a,b,x,m; int n;
        scanf("%I64d%I64d%I64d%I64d%d", &a,&b,&x,&m,&n);
        memset(delt,0,sizeof(delt));
        memset(isi,0,sizeof(isi));
        int initn = n;
//        vector<int> delrows;
        // init
        x%=m;
        set<pair<int,int> > coldata[6];

        int q;
        scanf("%d", &q);

        Node* roots[10];
        memset(roots, 0, sizeof(roots));
        
        vector<int> que[6];
        
        for (int i=1;i<=n;i++){
            for (int j=1;j<=5;j++){
                isi[i][j]=((a*isi[i-1][j])%m+(b*isi[i][j-1])%m+x)%m;
                coldata[j].insert(make_pair(isi[i][j], i));
                
                que[j].push_back(isi[i][j]);                 
            }
        }
        for (int i=1;i<=5;i++)
            random_shuffle(que[i].begin(), que[i].end());
        
        for (int i=0;i<n;i++){
            for (int j=1;j<=5;j++){
                if (!roots[j]){
                    roots[j] = make_Node(que[j][i]);
                } else {
                    insert(roots[j], que[j][i]);
                }     
            }
        }        
                
        printf("Case #%d:\n", ttc);
        
        
        
        for (int i=0;i<q;i++){
            scanf("%s", buffer);
            if (!strcmp(buffer, "insert")){
                n++;                
                int p,q,r,s,t;
                scanf("%d%d%d%d%d", &p,&q,&r,&s,&t);
                isi[n][1]=p;
                isi[n][2]=q;
                isi[n][3]=r;
                isi[n][4]=s;
                isi[n][5]=t;
                coldata[1].insert(make_pair(p,n));
                coldata[2].insert(make_pair(q,n));
                coldata[3].insert(make_pair(r,n));
                coldata[4].insert(make_pair(s,n));
                coldata[5].insert(make_pair(t,n));
                
                if (!roots[1]){
                    roots[1] = make_Node(p);
                } else {
                    insert(roots[1], p);
                }      
                if (!roots[2]){
                    roots[2] = make_Node(q);
                } else {
                    insert(roots[2], q);
                }      
                if (!roots[3]){
                    roots[3] = make_Node(r);
                } else {
                    insert(roots[3], r);
                }      
                if (!roots[4]){
                    roots[4] = make_Node(s);
                } else {
                    insert(roots[4], s);
                }      
                if (!roots[5]){
                    roots[5] = make_Node(t);
                } else {
                    insert(roots[5], t);
                }      
            } else if (!strcmp(buffer, "remove")){
                int ln;
                scanf("%d" , &ln);
                if (ln<=n)
                if (!delt[ln]){
                    delt[ln]=1;
                    for (int i=1;i<=5;i++){
                        buang(roots[i], isi[ln][i]);
                        coldata[i].erase(make_pair(isi[ln][i],ln));
                    }
                }
            } else if (!strcmp(buffer, "max")){
                int cn;
                scanf("%d", &cn);
                set<pair<int,int> >::reverse_iterator it = coldata[cn].rbegin();
                /*
                while (delt[(*it).second]){
                    it++;
                }*/
                printf("%d\n", (*it).first);
            } else if (!strcmp(buffer, "min")){
                int cn;
                scanf("%d", &cn);
                set<pair<int,int> >::iterator it = coldata[cn].begin();
                /*
                while (delt[(*it).second]){
                    it++;
                }*/
                printf("%d\n", (*it).first);
                
            } else {
                // range   
                int cn,a,b;
                scanf("%d%d%d",&cn, &a,&b);
                if (a>b) swap(a,b);
                int res = countBetween(roots[cn], a,b,0,0);
                /*
                for (int d=0;d<delrows.size();d++){
                    int rn = delrows[d];
                    int data = isi[rn][cn];
                    if (data>=a && data<=b) res--;
                }*/
                
                printf("%d\n",res);                                             
            }
        }/*
        bantai(roots[1]);
        bantai(roots[2]);
        bantai(roots[3]);
        bantai(roots[4]);
        bantai(roots[5]);*/
    }
    
    return 0;
}

Please note that the document shown may be copyrighted. Please contact the owner of this document for the details.
Valid XHTML and CSS. Powered by Ruby on Rails.
 
Copyright © 2008 by Andrian Kurniady. All rights reserved.