POJ2985 Union search + line segment tree to find the kth largest number

In fact, I have done this question before, and I have never been familiar with the line segment tree, so I have never understood it.

The key to this question is that the original interval of the line segment tree represents the number of each container (different size)

For example, they are unrelated to each other at the beginning, so the container of 1 has n 2 3 4. . . to 0

The additional information of each node of the segment tree is the sum of the interval

The code found in this question is the key. For example, if the left and right subtrees are sum 27 25 respectively, then the 26th largest container must be on the left subtree, and if the recursion continues, we need to find a (26-25) large container in the left subtree. . . .

 

In layman's terms, this question is to change the point, modify the summation change (additional information), and just convert it with k.

 

The line segment tree is still too little, and special training will be strengthened in the near future.

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
#include <ctime>

using namespace std;

//#define EdsonLin

#ifdef EdsonLin
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...)
#endif //EdsonLin

typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f;
const int MAXN = 2e5+10;
const int MAXNN = 2e6+100;
//const int MAXM = 1e6;
//const int MAXM = 3e4+100;
const int MOD = 1000000007;
const db eps = 1e-3;
#define PB push_back

int a[MAXN],p[MAXN];
int n,m,k;
int readint(){
     int x;scanf("%d",&x);return x;}
int Find(int x){
     return (x==p[x]?x:Find(p[x]));}
void Union(int u,int v){p[u] = Find(u);p[v] = Find(v);p[p[v]] = p[u];}
void init(){
    for(int i=1;i<=n;i++){
     
     
        a[i] = 1;
        p[i] = i;
    }
}

struct sT{
    int sum[MAXN*3];
    int n;
    void popup(int o){
        int lc = o*2;
        int rc = o*2|1;
        sum[o] = sum[lc] + sum[rc];
    }
    void build(int o,int lc,int rc){
        if(lc==1)sum[o] = n;
        else sum[o] = 0;
        if(lc==rc)return;
        if(lc<rc){
            int mc = lc + (rc-lc)/2;
            build(o*2,lc,mc);
            build(o*2|1,mc+1,rc);
        }
    }
    void update( int o, int lc, int rc, int val, int c){
         int mc = lc + (rc-lc)/ 2 ;
         if (lc==rc&&lc==val){sum[o] += c ; return ;}
         if (lc==rc) return ;
         if (mc<val)update(o* 2 | 1 ,mc+ 1 ,rc,val,c);   // This step is easy to change all val-related nodes by mistake info 
        else update(o* 2 ,lc,mc,val,c);
        popup(o);    // Recurse up, change the parent node additional information 
    }
     void query( int o, int lc, int rc, int k){
         if (lc== rc){
            printf("%d\n",lc);
            return;
        }
        int mc = lc+(rc-lc)/2;
        if(k<=sum[o*2|1])query(o*2|1,mc+1,rc,k);
        else query(o*2,lc,mc,k-sum[o*2|1]);
    }
    void init(){
        memset(sum,0,sizeof(sum));
        this->n = n;
    };
}solver;


intmain ()
{
    while(cin>>n>>m){
        init();
        solver.init();
        solver.build(1,1,n);
        for(int i=0;i<m;i++){
            int sg;
            scanf("%d",&sg);
            if(!sg){
                int u,v;
                scanf("%d%d",&u,&v);
                u = Find(u);
                v = Find(v);
                if(u==v)continue;
                /*Union(u,v);*/
                p[v] = u;
                solver.update(1,1,n,a[u],-1);
                solver.update(1,1,n,a[v],-1);
                solver.update(1,1,n,a[u]+a[v],1);
                a[u] += a[v];
            }else{
                scanf("%d",&k);
                solver.query(1,1,n,k);
            }
        }
    }
    //cout << "Hello world!" << endl;
    return 0;
}
View Code

 

Reprinted in: https://www.cnblogs.com/EdsonLin/p/5643775.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326486506&siteId=291194637