[HDU_3071 Gcd & Lcm game prime decomposition + + segment tree-like pressure]

I, entitled

   Gcd & Lcm game 

Second, analysis

  A very good question.

  First, consider the relatively violent approach, certainly Yaoan range for processing, for $ lcm $ and $ gcd $ can be evaluated using the standard formula, but when seeking $ lcm $ is sure to burst the $ long long $.

  Consider prime decomposition, after all the factorization, found limited number of prime factors, each factor and the power is limited, i.e. up to $ 2 ^ _6 $, then the prime factors may be considered in every binary It is expressed. For $ 2,3,5,7 $ might want more, so give it to a few, and finally found, just to within $ 32 $ bit.

  Here it is necessary to write two conversion functions, then using the properties of $ gcd $ and $ lcm $ is solved and transformation. Finally, consider the range query and modify a single point, and then a segment tree can be.  

Three, AC codes

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
#define ll long long
#define Min(a,b) ((a)>(b)?(b):(a))
#define Max(a,b) ((a)>(b)?(a):(b))
#define lson (rt<<1)
#define rson (rt<<1|1)
const int MAXN = 1e5;
struct Node
{
    int L, G;
}segTree[MAXN<<2];
int Prime[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
int Pos[25] = {28,25 , 23 , 21 , 20 , 19 , 18 , 17 , 16 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 }; 

inline 're GCD ( you get, you y) 
{ 
    //Finally, phase &, if it continues with Min, the equivalent of only one lead WA 
    return Min (the X-& 0x70000000 , the y-& 0x70000000 ) | Min (the X-& 0x0e000000 , the y-& 0x0e000000 ) | Min (the X-& 0x01800000 , the y-& 0x01800000 ) | Min (the X-& 0x00600000 , Y & 0x00600000 ) | ((X & 0x001FFFFF ) & (Y & 0x001FFFFF )); 
} 
inline int of Lcm ( int X, int Y) 
{ 
    return Max (X & 0x70000000 , Y & 0x70000000 ) | Max (X & 0x0e000000 , Y & 0x0e000000) | Max (x & 0x01800000 , Y & 0x01800000 ) | Max (x & 0x00600000 , Y & 0x00600000 ) | ((x & 0x001FFFFF ) | (Y & 0x001FFFFF )); 
} 
// x-quality factorization, and is expressed in binary 
inline int Turn ( int x ) 
{ 
    int RES, ANS = 0 ;
     for ( int I = 0 ; I < 25 && X> . 1 ; I ++ ) { 
        RES = 0 ;
         the while (X% Prime [I] == 0  ) {
            RES++;
            x/=Prime[i];
        }
        ans |= (res<<Pos[i]);
    }
    return ans;
}

int Mi2[] = {1, 2, 4, 8, 16, 32, 64};
int Mi3[] = {1, 3, 9, 27, 81};
int Mi5[] = {1, 5, 25};
int  Mi7[] = {. 1 , . 7 , 49 }; 

// the number of binary representation of the number of original and changed around modulo 
inline int the Get ( int X, int P) 
{ 
    LL ANS = . 1 ;
     int RES >> Pos X = [ 0 ]; 
    X ^ = RES << Pos [ 0 ];    // erase the bits represents a number of 2 
    ANS = ANS * Mi2 [RES]% P;
     // exponential 3 and erasing 
    RES >> Pos X = [ . 1 ]; ^ = X << RES Pos [ . 1 ]; * ANS ANS = Mi3 [RES]% P;
     // exponential 5 and erasing 
    res = x >> Pos [ 2];    x ^= res<<Pos[2];   ans = ans * Mi5[res] % p;
    //求7的指数并消去
    res = x>>Pos[3];    x ^= res<<Pos[3];   ans = ans * Mi7[res] % p;
    for(int i = 4; i < 25; i++) {
        if((x>>Pos[i])&1) {
            ans = ans * Prime[i] % p;
        }
    }
    return ans % p;
}

void Push_up(int rt)
{
    segTree[rt].G = Gcd(segTree[lson].G, segTree[rson].G);
    segTree[rt].L = Lcm(segTree[lson].L, segTree[rson].L);
    return;
}

void Build(int rt, int l, int r)
{
    if(l == r) {
        int a;
        scanf("%d", &a);
        segTree[rt].G = Turn(a);
        segTree[rt].L = Turn(a);
        return;
    }
    int mid = (l + r) >> 1;
    Build(lson, l, mid);
    Build(rson, mid + 1, r);
    Push_up(rt);
}

void Change(int rt, int l, int r, int pos, int val)
{
    if(l == r) {
        segTree[rt].G = Turn(val);
        segTree[rt].L = segTree[rt].G;
        return;
    }
    int mid = (l + r) >> 1;
    if(pos <= mid) {
        Change(lson, l, mid, pos, val);
    }
    else if (pos > mid) {
        Change(rson, mid + 1, r, pos, val);
    }
    Push_up(rt);
}

int anslcm, ansgcd;
void Query_lcm(int rt, int l, int r, int L, int R)
{
    if(L <= l && r <= R) {
        anslcm = Lcm(anslcm, segTree[rt].L);
        return;
    }
    int mid = (l + r) >> 1;
    if(L <= mid) {
        Query_lcm(lson, l, mid, L, R);
    }
    if(R > mid) {
        Query_lcm(rson, mid + 1, r, L, R);
    }
}
void Query_gcd(int rt, int l, int r, int L, int R)
{
    if(L <= l && r <= R) {
        ansgcd = Gcd(ansgcd, segTree[rt].G);
        return;
    }
    int mid = (l + r) >> 1;
    if(L <= mid) {
        Query_gcd(lson, l, mid, L, R);
    }
    if(R > mid) {
        Query_gcd(rson, mid + 1, r, L, R);
    }
}
int main()
{
    //freopen("input.txt", "r", stdin);
    int N, Q;
    while(scanf("%d%d", &N, &Q) != EOF) {
        Build(1, 1, N);
        char s[2];
        for(int i = 0; i < Q; i++) {
            scanf("%s", s);
            int a, b, c;
            if(s[0] == 'L') {
                anslcm = 0;
                scanf("%d%d%d", &a, &b, &c);
                Query_lcm(1, 1, N, a, b);
                int ans = Get(anslcm, c);
                printf("%d\n", ans);
            }
            else if(s[0] == 'G') {
                ansgcd = 0x7fffffff;
                scanf("%d%d%d", &a, &b, &c);
                Query_gcd(1, 1, N, a, b);
                int ans = Get(ansgcd, c);
                printf("%d\n", ans);
            }
            else {
                scanf("%d%d", &a, &c);
                Change(1, 1, N, a, c);
            }
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/dybala21/p/11431591.html