게시판 즐겨찾기
편집
드래그 앤 드롭으로
즐겨찾기 아이콘 위치 수정이 가능합니다.
죄송합니다 저장용으로 좀 쓰겠습니다
게시물ID : freeboard_775921짧은주소 복사하기
작성자 : 할말이있어
추천 : 1
조회수 : 192회
댓글수 : 0개
등록시간 : 2014/07/26 23:29:29
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

typedef long long ll;

int rmax, cmax;

inline ll gcd(ll a, ll b) {
    if(b>a) return gcd(b, a);
    if(b==0) return a;
    if(a%2==0 && b%2==0) return 2*gcd(a/2, b/2);
    if(a%2==0 && b%2==1) return gcd(a/2, b);
    if(a%2==1 && b%2==0) return gcd(a, b/2);
    return gcd((a-b)/2, b);
}

ll DIGIT_BITS=30;
ll BASE = 1 << DIGIT_BITS;

ll nbits(ll n) {
    return floor(log2(n))+1;
}

inline ll lehmer_gcd(ll a, ll b) {
    if(a<b) return lehmer_gcd(b, a);
    while(b >= BASE) {
        ll push = nbits(a) - DIGIT_BITS;
        ll x = a >> push;
        ll y = b >> push;
        ll A=1, B=0, C=0, D=1;
        while(1) {
            if(y+C==0 || y+D==0) break;
            ll q = (x+A) / (y+C);
            if(q!=(x+B)/(y+D)) break;
            ll tempA=A, tempB=B, tempx=x;
            A=C; B=D; x=y;
            C=tempA-q*C; D=tempB-q*D; y=tempx-q*y;
        }
        if(B) {
            ll tempa = a;
            a = A*a + B*b;
            b = C*tempa + D*b;
        }
        else {
            ll tempa = a;
            a = b;
            b = tempa % b;
        }
    }
    return gcd(a, b);
}

class LONG {
private:
    ll value;
public:
    LONG(ll v) {
        value = v;
    }
    ll getvalue() {
        return value;
    }
    void setvalue(ll v) {
        value = v;
    }
};

template<class DataType> class TreeNode{
private:
    int l;
    int r;
    DataType* Data;
    TreeNode* Left;
    TreeNode* Right;
public:
    static int rmax;
    static int cmax;
    TreeNode() {
        TreeNode(0, 0);
    }
    TreeNode(int l, int r) {
        this->l = l;
        this->r = r;
        Data = NULL;
    }
    TreeNode(int l, int r, DataType& Data) {
        this->Data = &Data;
    }
    void setInterval(int l, int r) {
        this->l = l;
        this->r = r;
    }
    void setData(DataType& Data) {
        this->Data = &Data;
    }
    friend ll queryIN(TreeNode<LONG>* TN, int l, int r);
    friend ll queryOUT(TreeNode<TreeNode<LONG> >* TN, int cl, int cr, int rl, int rr);
    friend ll updateIN(TreeNode<LONG>*, int, ll);
    friend void updateOUT(TreeNode<TreeNode<LONG> >*, int, int, ll);
};

typedef TreeNode<LONG> InnerTree;
typedef TreeNode<TreeNode<LONG> > OuterTree;

ll queryIN(InnerTree* TN, int l, int r) {
    if(TN==NULL) return 0;
    if(r < TN->l || TN->r < l) return 0;
    if(l <= TN->l && TN->r <= r) return TN->Data->getvalue();
    return gcd(queryIN(TN->Left, l, r), queryIN(TN->Right, l, r));
}

ll queryOUT(OuterTree *TN, int cl, int cr, int rl, int rr) {
    if(TN==NULL) return 0;
    if(cr < TN->l || TN->r < cl) return 0;
    if(cl <= TN->l && TN->r <= cr) return queryIN(TN->Data, rl, rr);
    return gcd(queryOUT(TN->Left, cl, cr, rl, rr), queryOUT(TN->Right, cl, cr, rl, rr));
}

ll updateIN(InnerTree* TN, int r, ll k) {
    if(TN->l == TN->r) {
        TN->Data->setvalue(k);
        return k;
    }
    if(r <= (TN->l + TN->r)/2) {
        if(TN->Left == NULL) {
            TN->Left = new InnerTree(TN->l, (TN->l + TN->r)/2);
        }
        ll other = (TN->Right == NULL ? 0 : TN->Right->Data->getvalue());
        TN->Data->setvalue(lehmer_gcd(updateIN(TN->Left, r, k), other));
    }
    else {
        if(TN->Right == NULL) {
            TN->Right = new InnerTree((TN->l + TN->r)/2 + 1, TN->r);
        }
        ll other = (TN->Left == NULL ? 0 : TN->Left->Data->getvalue());
        TN->Data->setvalue(lehmer_gcd(updateIN(TN->Right, r, k), other));
    }
    return TN->Data->getvalue();
}

void updateOUT(OuterTree* TN, int r, int c, ll k) {
    if(TN->Data == NULL) {
        TN->Data = new InnerTree(0, rmax);
    }
    updateIN(TN->Data, r, k);
    if(TN->l == TN->r) return;
    if(c <= (TN->l + TN->r)/2) {
        if(TN->Left == NULL) {
            TN->Left = new OuterTree(TN->l, (TN->l + TN->r)/2);
        }
        updateOUT(TN->Left, r, c, k);
    }
    else {
        if(TN->Right == NULL) {
            TN->Right = new OuterTree((TN->l + TN->r)/2 + 1, TN->r);
        }
        updateOUT(TN->Right, r, c, k);
    }
}

int main() {
    //ifstream cin;
    //cin.open("input.txt");
    int r, c, n, command;
    int cl, cr, rl, rr;
    int k;
    int i;
    cin >> r >> c >> n;

    OuterTree * OutTree = new OuterTree(0, c-1);

    rmax = r-1;
    cmax = c-1;

    for(i=0; i<n; i++) {
        cin >> command;
        if(command==1) {
            cin >> rl >> cl;
            cin >> k;
            updateOUT(OutTree, rl, cl, k);
        }
        else {
            cin >> rl >> cl >> rr >> cr;
            cout << queryOUT(OutTree, cl, cr, rl, rr) << endl;
        }
    }
    //cin.close();
    return 0;
}
 
전체 추천리스트 보기
새로운 댓글이 없습니다.
새로운 댓글 확인하기
글쓰기
◀뒤로가기
PC버전
맨위로▲
공지 운영 자료창고 청소년보호