Cod sursa(job #1368808)

Utilizator jordasIordache Andrei Alexandru jordas Data 2 martie 2015 20:05:16
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.57 kb
#include <fstream>
#define nMax 100001

using namespace std;

 ifstream x ("arbint.in");
 ofstream y ("arbint.out");

 struct node
 {
     int key;
     int l,r;
     node *left,*right,*parent;
 };

 int l,r,maxx;
 int a[nMax];

 void generate(node *current)
 {
     if(current->l!=current->r)
     {
         node *temp;

         temp=new node();

         temp->key=0;
         temp->l=current->l;
         temp->r=current->l+(current->r-current->l)/2;
         temp->left=NULL;
         temp->right=NULL;
         temp->parent=current;
         current->left=temp;

         temp=new node();

         temp->key=0;
         temp->l=current->l+(current->r-current->l)/2+1;
         temp->r=current->r;
         temp->left=NULL;
         temp->right=NULL;
         temp->parent=current;
         current->right=temp;

         generate(current->left);
         generate(current->right);
     }
 }

 int generate_min(node *current)
 {
     if(current->left)
        if(current->right)
           current->key=max(generate_min(current->left),generate_min(current->right));
        else
           current->key=current->left->key;
     else
        current->key=a[current->l];

     return current->key;
 }

 void find_max(node *current)
 {
     if(current->l>=l && current->r<=r)
        maxx=max(maxx,current->key);
     else
     {
         if(current->l>=l && current->left->r<r)
            find_max(current->left);

         if(current->r<=r && current->right->l>l)
            find_max(current->right);

         if(current->l<l)
            if(l<=current->l+(current->r-current->l)/2)
               find_max(current->left);
            else
               find_max(current->right);

         if(current->r>r)
            if(r>=current->l+(current->r-current->l)/2+1)
               find_max(current->right);
            else
               find_max(current->left);
     }
 }

 void modify(node *current)
 {
     if(current->parent)
     {
         if(current->key>current->parent->key)
         {
             current->parent->key=current->key;

             modify(current->parent);
         }

         if(current->key<current->parent->key)
         {
             current->parent->key=max(current->parent->left->key,current->parent->right->key);

             modify(current->parent);
         }
     }
 }

 void locate(node *current)
 {
     if(current->l==current->r && current->l==l)
     {
         current->key=r;
         modify(current);
     }
     else
        if(l<=current->l+(current->r-current->l)/2)
           locate(current->left);
        else
           locate(current->right);
 }

 void dfs(node *current)
 {
     y<<current->l<<"  "<<current->r<<" --> "<<current->key<<"\n";

     if(current->l!=current->r)
     {
         dfs(current->left);
         dfs(current->right);
     }
 }

int main()
{
    int n,m;

    x>>n>>m;

    int i;

    for(i=1;i<=n;i++)
       x>>a[i];

    node *root;

    root=new node();

    root->key=0;
    root->l=1;
    root->r=n;
    root->left=NULL;
    root->right=NULL;
    root->parent=NULL;

//Preprocesare
    generate(root);
    generate_min(root);

    //dfs(root);
    //y<<'\n';

    int t;

    for(i=1;i<=m;i++)
    {
        //y<<'\n';
        //dfs(root);

        x>>t;
        x>>l>>r;

        if(t==0)
        {
            maxx=0;
            find_max(root);
            y<<maxx<<'\n';
        }
        else
        {
            locate(root);
        }
    }



    return 0;
}