• + 1 comment

    include

    include

    include

    include

    include

    using namespace std;

    long Max = 1000000; long N; long Root;

    struct Node { long long value = 0; long height = 0; vector childNoes; };

    void DeLinkParentFromChild(long R, Node* arr, long P, long height) { Node* node = &arr[R]; node->height = height; int size = node->childNoes.size(); for(long i = 0; i < size; ++i) { long index = node->childNoes[i]; if(index > N) continue;

        if(index == P)
        {
            node->childNoes[i] += Max;
        }
        else
            DeLinkParentFromChild(index, arr, R, height+1);
    }
    

    }

    void AddValue(Node* arr, long T, int K, long long value) { Node* node = &arr[T]; node->value += value;

    long long nextValue = value + K;
    int size = node->childNoes.size();
    for(long i = 0; i < size;++i)
    {
        long index = node->childNoes[i];
        if(index > N)
            continue;
        AddValue(arr, index, K, nextValue);
    }
    

    }

    void GetSum(Node* arr, long A, long B, long long& sum, bool& bFound) { while (arr[A].height > arr[B].height) { Node* node = &arr[A]; sum += node->value;

        int size = node->childNoes.size();
        for (long i = 0; i < size; ++i)
        {
            long index = node->childNoes[i];
            if (index <= N)
                continue;
            A = index-Max;
            break;
        }
    }
    
    while (arr[A].height < arr[B].height)
    {
        Node* node = &arr[B];
        sum += node->value;
    
        int size = node->childNoes.size();
        for (long i = 0; i < size; ++i)
        {
            long index = node->childNoes[i];
            if (index <= N)
                continue;
            B = index-Max;
            break;
        }
    }
    
    if (A == B)
    {
        sum += arr[A].value;
        bFound = true;
        return;
    }
    
    while (arr[A].height > 0)
    {
        Node* nodeA = &arr[A];
        sum += nodeA->value;
        int size = nodeA->childNoes.size();
        for (long i = 0; i < size; ++i)
        {
            long index = nodeA->childNoes[i];
            if (index <= N)
                continue;
            A = index-Max;
            break;
        }
    
        Node* nodeB = &arr[B];
        sum += nodeB->value;
        size = nodeB->childNoes.size();
        for (long i = 0; i < size; ++i)
        {
            long index = nodeB->childNoes[i];
            if (index <= N)
                continue;
            B = index-Max;
            break;
        }
    
    
        if (A == B)
        {
            sum += arr[A].value;
            bFound = true;
            return;
        }
    }
    

    }

    int main() {
    long E; long R;

    cin>>N>>E>>R;
    Root = R;
    
    Node* arr = new Node[N+1];  
    
    for(long i = 0; i < N-1;++i)
    {
        long X, Y;
        cin>>X>>Y;
        arr[X].childNoes.push_back(Y);
        arr[Y].childNoes.push_back(X);
    }  
    
    DeLinkParentFromChild(R, arr, -1, 0);
    
    for(long i = 0; i < E;++i)
    {
       char ch;
       cin>>ch;
       if(ch == 'U')
       {           
           long T, V, K;
           cin>>T>>V>>K;
           AddValue(arr, T, K, V);
       }
       else if(ch == 'Q')
       {            
           long A, B;
           cin>>A>>B;
    
           long long sum = 0;
           bool bFound = false;
           GetSum(arr, A, B, sum, bFound);
           if(!bFound)
            sum = 0;
           cout<<sum%(1000000007)<<endl;
       }
    }
    
    return 0;
    

    }