P2709 small B inquiry - General Mo team && Templates

Mo ordinary team concept

Team Mo: Mo algorithm Tao captain invention, Mo revered team. In fact, the optimization of violence.

Mo team only ordinary magnetic hereby asked not be modified, is offline.

Mo team's basic idea : that assumes that I got an inquiry interval [l, r] answer, then I can get [l + 1, r] in the complexity in a very short (usually O (1)) time then transfer back and forth for the title after the interval query like, I can read all one-time inquiries, to get an answer for each interval - the answer.

If by the interval [l, r] quickly transferred to [l1, r] [l + 1, r] [l, r-1] [l, r + 1], it can be O (x * | l1 -l2 | + | r1-r2 | ) time to complete the transfer, [l2, r2] is [l1, r1] after the first inquiry, x is [l, r] go to the complexity of the adjacent section, we let this the minimum value, is seeking Manhattan from the minimum spanning tree, but this is more difficult to find. With a certain rule can be ordered by block, the block number to the left of the point at which the first sort key, the second key value as a sort of a right end point, the above worst complexity and Manhattan distance is the same minimum spanning tree and the way to do this complexity is $ O (n \ sqrt n) $ ( will not permit, anyway, after the use of the block is this complexity ).

Here, the role of the block is accelerating it.

topic

B has a small sequence contains an integer between 1 ~ K N number. He asks a total of M, each interrogation a given interval [L..R], seeking Sigma (c (i) ^ 2) value, wherein the value of i from 1 to K, where c (i) represents a number i number of repetitions [L..R] in

analysis:

Do not modify the template the team title, recording the number of times each number appears in the current range with an array transferred in Mozambique team is maintained.

First read all the queries and sorting, and completion pointer jump results obtained for each query, and finally outputs the result sorted according to the query sequence.

There are two ways to sort the query:

  • A left end point where the block number is the first sort key, the value of the right point as the second sort key
  • A left end point where the block number is the first sort key, the block number is the same, if it is an odd number block in ascending r, descending or
#include <bits / STDC ++ H.>
 the using  namespace STD; 

typedef Long  Long LL;
 const  int MAXN = 50000 + 10 ;
 struct Que {
     int L, R & lt, ID;    // ID inquiry indicates how many times 
    LL RES;      // current answer to the inquiry 
} Q [MAXN]; 

int n-, m, K; 
LL block [MAXN], NUM [MAXN], SUM [MAXN], size; 
LL ANS; 
// block: block size array block size
 / / SUM [i]: i is the number of elements 

void the init () 
{ 
    size = ( int ) sqrt (n-);
     for( Int I = . 1 ; I <= n-; I ++) Block [I] = (I- . 1 ) / size + . 1 ; 
} 

// Do a team spirit 
BOOL CMP (Que X, Y Que) 
{ 
    return Block [XL] Block == [YL] XR <YR:? XL < YL; 
} 

BOOL CMPP (Que X, Y Que) // second sort, faster 
{
     return (Block [XL] ^ Block [YL]) Block? [XL] <Block [YL]: ((Block [XL] & . 1 ) XR <YR: XR>? YR); 
} 

// press queries sequentially and for outputting the answer 
BOOL   CMP_ID (Que X, Y Que) 
{ 
    return x.id <  y.id;
} 

//Two teams essence MO: transfer 
void Modify ( int X, int W) 
{ 
    ANS - = sum [NUM [X]] * sum [NUM [X]];   /// first square sum of the original position by subtracting this number 
    SUM [NUM [X]] = + W;        // update count the number of array 
    ANS = SUM + [NUM [X]] * SUM [NUM [X]];   // then add new SUM 
} 

void Solve () 
{ 
    int L = . 1 , R & lt = 0 ;   // Mo essence three teams: two small hand jump back and forth, indicating the current maintenance interval around ans endpoint 
    for ( int I = . 1 ; I <= m; I ++ ) 
    { 
        the while ( R & lt <Q [I] .r) Modify (R & lt + . 1, 1), r++;
        while(r > q[i].r)  modify(r, -1), r--;
        while(l < q[i].l)  modify(l, -1), l++;
        while(l > q[i].l)  modify(l-1, 1), l--;
        q[i].res = ans;
    }
}

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1;i <= n;i++)  scanf("%lld", &num[i]);
    for(int i = 1;i <= m;i++)
    {
        scanf("%d%d", &q[i].l, &q[i].r);
        q[i].id = i;
    }

    init();
    sort(q+1, q+m+1, cmp);  //or cmpp

    solve();

    sort(q+1, q+m+1, cmp_id);
    for(int i = 1;i <= m;i++)
        printf("%lld\n", q[i].res);

    return 0;
}

 

 

Reference links:

1. https://www.luogu.org/problemnew/solution/P2709?page=2

2. https://www.luogu.org/problemnew/solution/P1494

Guess you like

Origin www.cnblogs.com/lfri/p/11203977.html