Cod sursa(job #163027)

Utilizator FlorinC1996Florin C FlorinC1996 Data 21 martie 2008 09:21:38
Problema Eprubeta Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 7.92 kb
 #include <stdio.h>   
#include <stdlib.h>   
#include <algorithm>   
  
using namespace std;   
  
#define MAX_N 2048   
#define INF 0x3f3f3f3f   
#define MAX_PRIORITY 32767   
#define FIN "eprubeta.in"   
#define FOUT "eprubeta.out"   
#define update(n) ((n)->sum = (n)->l->sum + (n)->r->sum + (n)->val)   
  
struct node    
{   
    short key, p;   
    int val, sum;   
    node *l, *r;   
} *L[MAX_N], *R[MAX_N], *NIL;   
  
int N, M, A, B, X, V[MAX_N];   
  
inline void rotleft(node *&n) { node *t = n->l; n->l = t->r; update(n); t->r = n; n = t; update(n); }   
inline void rotright(node *&n) { node *t = n->r; n->r = t->l; update(n); t->l = n; n = t; update(n); }   
  
inline node* new_node(short key, int val, short p, node *l, node *r)    
{    
    node *t = new node;    
    t->key = key; t->val = val; t->p = p;    
    t->l = l; t->r = r;    
    return t;    
}   
  
void insert(node *&n, short key, int val, short p)   
{   
    if (n == NIL)   
    {   
        n = new_node(key, val, p, NIL, NIL);   
        update(n);   
        return;   
    }   
    if (key < n->key)   
    {   
        insert(n->l, key, val, p);   
        if (n->l->p > n->p) rotleft(n);   
    }   
    else    
    {   
        insert(n->r, key, val, p);   
        if (n->r->p > n->p) rotright(n);   
    }   
    update(n);   
}   
  
void erase(node *&n)   
{   
    if (n->l == NIL && n->r == NIL) { delete n; n = NIL; return; }   
    if (n->l->p > n->r->p)   
    {   
        rotleft(n);   
        erase(n->r);   
    }   
    else  
    {   
        rotright(n);   
        erase(n->l);   
    }   
    update(n);   
}   
  
void erase(node *&n, short key)   
{   
    if (n == NIL) return;   
    if (key < n->key) { erase(n->l, key); return; }   
    if (key > n->key) { erase(n->r, key); return; }   
    erase(n);   
}   
  
node* join(node *n1, node *n2)   
{   
    node *n = new_node(0, 0, MAX_PRIORITY, n1, n2);   
    erase(n);   
    return n;   
}   
  
node* split(node *&n, short key)   
{   
    node *n1, *n2;   
  
    insert(n, key, 0, MAX_PRIORITY);   
    n1 = n->l; n2 = n->r;   
    delete n;   
    n = n2;    
    return n1;   
}   
  
void rotate(node *&n1, node *&n2, int size)   
{   
    node *t1, *t2;   
  
    t1 = split(n1, size);   
    t2 = split(n2, size);   
    n2 = join(t1, n2);   
    n1 = join(t2, n1);   
}   
  
int get_sum(node *n, short key)   
{   
    if (n == NIL) return 0;   
    if (key < n->key) return get_sum(n->l, key);   
    if (key == n->key) return n->l->sum+n->val;   
    return n->l->sum+n->val+get_sum(n->r, key);   
}   
  
int main(void)   
{   
    int i, j, k, x, sum;   
  
    freopen(FIN, "r", stdin);   
    freopen(FOUT, "w", stdout);   
  
    scanf("%d %d %d %d %d", &N, &M, &X, &A, &B);   
  
    NIL = new_node(0, 0, -MAX_PRIORITY, NULL, NULL);   
    NIL->sum = 0;   
  
    for (i = 0; i < N; ++i)   
    {   
        L[i] = R[i] = NIL;   
        for (j = 0; j < N; ++j)   
        {   
            x = ((i+A)*(j+B)/4) % X;   
            if (j < i) insert(L[i], i-j, x, rand()%MAX_PRIORITY);   
            if (j > i) insert(R[i], j-i, x, rand()%MAX_PRIORITY);   
            if (j == i) V[i] = x;   
        }   
    }   
  
    for (; M; --M)   
    {   
        scanf("%d %d %d", &x, &i, &j);   
        if (x == 1)   
        {   
            for (x = k = j-i; i <= j; ++i, --j, --k)   
            {   
                rotate(L[j], R[i], k);   
                if (i != j) rotate(L[i], R[j], x-k);   
                swap(V[i], V[j]);   
            }   
        }   
        else    
        {   
            sum = 0;   
            for (x = k = j-i; i <= j; ++i, --k)   
            {   
                sum += get_sum(L[i], x-k);    
                sum += get_sum(R[i], k);   
                sum += V[i];   
            }   
            printf("%d\n", sum);   
        }   
    }   
  
    unsigned total_sum = 0;   
    for (i = 0; i < N; ++i)   
    {   
        x = L[i]->sum + R[i]->sum + V[i];   
        total_sum += (unsigned)x*(unsigned)x*(unsigned)(i+1);   
    }   
    printf("%u\n", total_sum);   
  
    return 0;   
}  
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;

#define MAX_N 2048
#define INF 0x3f3f3f3f
#define MAX_PRIORITY 32767
#define FIN "eprubeta.in"
#define FOUT "eprubeta.out"
#define update(n) ((n)->sum = (n)->l->sum + (n)->r->sum + (n)->val)

struct node 
{
    short key, p;
    int val, sum;
    node *l, *r;
} *L[MAX_N], *R[MAX_N], *NIL;

int N, M, A, B, X, V[MAX_N];

inline void rotleft(node *&n) { node *t = n->l; n->l = t->r; update(n); t->r = n; n = t; update(n); }
inline void rotright(node *&n) { node *t = n->r; n->r = t->l; update(n); t->l = n; n = t; update(n); }

inline node* new_node(short key, int val, short p, node *l, node *r) 
{ 
    node *t = new node; 
    t->key = key; t->val = val; t->p = p; 
    t->l = l; t->r = r; 
    return t; 
}

void insert(node *&n, short key, int val, short p)
{
    if (n == NIL)
    {
        n = new_node(key, val, p, NIL, NIL);
        update(n);
        return;
    }
    if (key < n->key)
    {
        insert(n->l, key, val, p);
        if (n->l->p > n->p) rotleft(n);
    }
    else 
    {
        insert(n->r, key, val, p);
        if (n->r->p > n->p) rotright(n);
    }
    update(n);
}

void erase(node *&n)
{
    if (n->l == NIL && n->r == NIL) { delete n; n = NIL; return; }
    if (n->l->p > n->r->p)
    {
        rotleft(n);
        erase(n->r);
    }
    else
    {
        rotright(n);
        erase(n->l);
    }
    update(n);
}

void erase(node *&n, short key)
{
    if (n == NIL) return;
    if (key < n->key) { erase(n->l, key); return; }
    if (key > n->key) { erase(n->r, key); return; }
    erase(n);
}

node* join(node *n1, node *n2)
{
    node *n = new_node(0, 0, MAX_PRIORITY, n1, n2);
    erase(n);
    return n;
}

node* split(node *&n, short key)
{
    node *n1, *n2;

    insert(n, key, 0, MAX_PRIORITY);
    n1 = n->l; n2 = n->r;
    delete n;
    n = n2; 
    return n1;
}

void rotate(node *&n1, node *&n2, int size)
{
    node *t1, *t2;

    t1 = split(n1, size);
    t2 = split(n2, size);
    n2 = join(t1, n2);
    n1 = join(t2, n1);
}

int get_sum(node *n, short key)
{
    if (n == NIL) return 0;
    if (key < n->key) return get_sum(n->l, key);
    if (key == n->key) return n->l->sum+n->val;
    return n->l->sum+n->val+get_sum(n->r, key);
}

int main(void)
{
    int i, j, k, x, sum;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    scanf("%d %d %d %d %d", &N, &M, &X, &A, &B);

    NIL = new_node(0, 0, -MAX_PRIORITY, NULL, NULL);
    NIL->sum = 0;

    for (i = 0; i < N; ++i)
    {
        L[i] = R[i] = NIL;
        for (j = 0; j < N; ++j)
        {
            x = ((i+A)*(j+B)/4) % X;
            if (j < i) insert(L[i], i-j, x, rand()%MAX_PRIORITY);
            if (j > i) insert(R[i], j-i, x, rand()%MAX_PRIORITY);
            if (j == i) V[i] = x;
        }
    }

    for (; M; --M)
    {
        scanf("%d %d %d", &x, &i, &j);
        if (x == 1)
        {
            for (x = k = j-i; i <= j; ++i, --j, --k)
            {
                rotate(L[j], R[i], k);
                if (i != j) rotate(L[i], R[j], x-k);
                swap(V[i], V[j]);
            }
        }
        else 
        {
            sum = 0;
            for (x = k = j-i; i <= j; ++i, --k)
            {
                sum += get_sum(L[i], x-k); 
                sum += get_sum(R[i], k);
                sum += V[i];
            }
            printf("%d\n", sum);
        }
    }

    unsigned total_sum = 0;
    for (i = 0; i < N; ++i)
    {
        x = L[i]->sum + R[i]->sum + V[i];
        total_sum += (unsigned)x*(unsigned)x*(unsigned)(i+1);
    }
    printf("%u\n", total_sum);

    return 0;
}