P3521 [POI2011] ROT-Tree Rotations (segment tree merge)

A topic intended (I do not have changed .....): n to a binary tree (1≤n≤200000 a leaf, you can exchange the left and right sub-tree for each point, the leaves reverse order traversal of the minimum requirements ago.

...... This annoying problem input is God na. . .

Give you a binary tree dfs sequence (not found on examination room 2333), only the leaf node has a value, and then seek to reverse the size

In the examination room, achievements built for a long time, then violent storm for a long time, then got 0 points, good results it (my awesome)

In fact, positive solution is not difficult to think (but was not the right value segment tree)

answer:

Is actually very simple, think about it: one for the reverse order, the number is certain. In other words, no matter how the current turn sub-tree, the number of reverse of the layer is not affected.

But still very good understanding of the Photo right:

For the second layer, whether of the left 2,3 how to change, in reverse order with respect to the right of the number 4,1 or 1,4 always will not change.

This property roar ah

So we only require a minimum number of reverse on the line within the block.

And then consider how to find the number in reverse order.

First, weights segment tree is a bucket, and subscript are ordered (nonsense)

Then, two courses weights in the segment tree is equivalent to this question, that is, about to merge tree line, in addition to the maintenance intervals && storage element is not the same, is the tree line and the conditions are met.

So, for an interval, only in reverse order to compare the left and the right half of the interval (bucket) * The number of right-range left half of the line,

Then after then compared swap, greedy to take down, merge down on the line.

..... language express a problem, look at this piece of code:

ans1+=(ll )t[t[l].rs].sum*t[t[r].ls].sum;
ans2+=(ll )t[t[l].ls].sum*t[t[r].rs].sum;

In this way, then add relatively small, the last is always the answer.

tips: really understand the benefits of pointers, a good use ah, but got to watch out, because change is a direct pointer value, some value can not be changed, starting an intermediate variable record.

#include<bits/stdc++.h>
using namespace std;
const int maxn=210000;
#define ll long long
struct tree
{
    int ls,rs,sum;
}t[maxn*30];
ll ans=0,ans1=0,ans2=0;
int n,pos;
int cnt=0;
void insert(int &x,int l,int r)
{
    if(!x)
    {
        x++ = CNT; 
    } 
    T [X] .sum ++ ;
     IF (L == R & lt) 
    { 
        return ; 
    } 
    int MID = (L + R & lt) >> . 1 ;
     IF (POS <= MID) 
    { 
        INSERT (T [ X] .ls, L, MID); 
    } 
    the else 
    { 
        INSERT (T [X] .RS, MID + . 1 , R & lt); 
    } 
} 
void merge ( int & L, int R & lt) // direct pointer combined, is better than the original write 
{
     IF (! L ||! R & lt) 
    { 
        L=l+r;
        return ;
    }
    t[l].sum+=t[r].sum;
    ans1+=(ll )t[t[l].rs].sum*t[t[r].ls].sum;
    ans2+=(ll )t[t[l].ls].sum*t[t[r].rs].sum;
    merge(t[l].ls,t[r].ls);
    merge(t[l].rs,t[r].rs);    
}
int work(int &x)
{
    int T,ls,rs;
    x=0;
    cin>>T;
    if(!T)
    {
        work(ls);
        work(rs);
        ans1=ans2=0 ; 
        X = LS; // pointer, starting intermediate variable storage 
        Merge (X, RS); 
        ANS + = min (ANS1, ANS2); 
    } 
    the else 
    { 
        POS = T; 
        INSERT (X, . 1 , n-); 
    } 
} 
int main () 
{ 
    Scanf ( " % D " , & n-);
     int T = 0 ; 
    Work (T); 
    the printf ( " % LLD " , ANS);
     return  0 ; 
}

(Finish)

 

Guess you like

Origin www.cnblogs.com/ajmddzp/p/11774785.html