zoukankan      html  css  js  c++  java
  • 计蒜客 2238 礼物 期望 + 线段树 + 归并

    题目链接:T2238   礼物  

    考虑 $[l,r]$ 区间中哪些二元组是优秀二元组:
    发现将二元组的 $x$ 按照从大到小排序,若 $y[i]$ 是这个前缀的最大值,则该二元组是优秀的.
    因为数据是随机的,所以前缀最大值期望是 $log(n)$ 个的.
    所以,我们可以用线段树来暴力存这些优秀的二元组.
    区间合并 $pushup$ 时运用类似归并排序的方式来进行合并即可.
    由于优秀二元组期望的数量是 $log$ 的,所以空间最多只会在原基础上乘一个 $log$.
    我的归并写的好丑~

    #include <cstdio> 
    #include <algorithm>
    #include <cstring>    
    #include <vector> 
    #define N 200006
    #define ll long long   
    #define mod 1000000007
    #define lson t[now].ls 
    #define rson t[now].rs 
    #define siz (t[now].v.size() - 1)
    #define setIO(s) freopen(s".in", "r" , stdin) , freopen(s".out", "w", stdout)     
    using namespace std;             
    int n ;           
    struct P 
    { 
        ll x , y;   
        P(ll x = 0, ll y = 0) : x(x), y(y) {}  
    }p[N]; 
    struct Node 
    {    
        int ls, rs ;          
        vector <P> v; 
    }t[N << 2];   
    vector <P> G, V, A;               
    inline void pushup(int L, int R, int now) 
    {      
        if(!rson) 
        {
            t[now].v = t[lson].v;        
        }
        else 
        {
            int p1 = 0, p2 = 0;      
            while(p1 < t[lson].v.size() && p2 < t[rson].v.size()) 
            { 
                if(t[lson].v[p1].x == t[rson].v[p2].x && t[lson].v[p1].y == t[rson].v[p2].y) ++p1, ++p2;   
                else if(t[lson].v[p1].x >= t[rson].v[p2].x && t[lson].v[p1].y >= t[rson].v[p2].y || t[lson].v[p1].x > t[rson].v[p2].x)    
                {          
                    if(t[now].v.empty() || t[lson].v[p1].y > t[now].v[t[now].v.size() - 1].y) 
                    {
                        t[now].v.push_back(t[lson].v[p1]);      
                    }           
                    ++ p1;         
                }     
                else if(t[rson].v[p2].x >= t[lson].v[p1].x && t[rson].v[p2].y >= t[lson].v[p1].y || t[rson].v[p2].x > t[lson].v[p1].x) 
                {
                    if(t[now].v.empty() || t[rson].v[p2].y > t[now].v[t[now].v.size() - 1].y) 
                    {
                        t[now].v.push_back(t[rson].v[p2]);    
                    } 
                    ++ p2; 
                }         
            }                  
            while(p1 < t[lson].v.size()) 
            {        
                if(t[now].v.empty() || (t[lson].v[p1].x <= t[now].v[siz].x && t[lson].v[p1].y > t[now].v[siz].y)) 
                    t[now].v.push_back(t[lson].v[p1]); 
                ++p1; 
            }
            while(p2 < t[rson].v.size()) 
            {
                if(t[now].v.empty() || (t[rson].v[p2].x <= t[now].v[siz].x && t[rson].v[p2].y > t[now].v[siz].y)) 
                    t[now].v.push_back(t[rson].v[p2]); 
                ++p2; 
            }
        }        
    }
    void build(int l, int r, int now) 
    { 
        if(l == r) 
        {      
            t[now].v.push_back(P(p[l].x, p[l].y));            
            return ;    
        } 
        int mid = (l + r) >> 1;        
        build(l, mid, now << 1), t[now].ls = now << 1; 
        if(r > mid)  build(mid + 1, r, now << 1 | 1), t[now].rs = now << 1 | 1;      
        pushup(l, r, now);             
    } 
    inline void query(int l, int r, int now, int L, int R) 
    {         
        if(l >= L && r <= R)  
        {     
            if(G.empty()) 
            {
                G = t[now].v;         
            }
            else 
            {          
                V = G, A = t[now].v;              
                G.clear();   
                // merge(V, A)     
                int p1 = 0, p2 = 0;      
                while(p1 < V.size() && p2 < A.size()) 
                { 
                    if(V[p1].x == A[p2].x && V[p1].y == A[p2].y) ++p1, ++p2; 
                    else if(V[p1].x >= A[p2].x && V[p1].y >= A[p2].y || V[p1].x > A[p2].x)    
                    {          
                        if(G.empty() || V[p1].y > G[G.size() - 1].y) 
                        {
                            G.push_back(V[p1]);      
                        }           
                        ++ p1;         
                    }     
                    else if(A[p2].x >= V[p1].x && A[p2].y >= V[p1].y || A[p2].x > V[p1].x) 
                    {
                        if(G.empty() || A[p2].y > G[G.size() - 1].y) 
                        {
                            G.push_back(A[p2]);    
                        } 
                        ++ p2; 
                    }          
                }    
                while(p1 < V.size()) 
                {
                    if(G.empty() || (V[p1].x <= G[G.size() - 1].x && V[p1].y > G[G.size() - 1].y)) 
                        G.push_back(V[p1]); 
                    ++p1; 
                }
                while(p2 < A.size()) 
                {
                    if(G.empty() || (A[p2].x <= G[G.size() - 1].x && A[p2].y > G[G.size() - 1].y)) 
                        G.push_back(A[p2]); 
                    ++p2; 
                }
            }   
            return; 
        } 
        int mid = (l + r) >> 1; 
        if(L <= mid) query(l, mid, now << 1, L, R);   
        if(R > mid) query(mid + 1, r, now << 1 | 1, L, R);    
    }
    int main() 
    {  
        int i , j, q;  
        scanf("%d" , &n);      
        for(i = 1; i <= n ; ++i)
        {
            scanf("%lld%lld", &p[i].x, &p[i].y);                  
        }
        build(1, n, 1), scanf("%d", &q);         
        for(int cas = 1; cas <= q; ++cas) 
        {
            int l, r; 
            scanf("%d%d", &l, &r);      
            G.clear();   
            query(1, n, 1, l, r);    
            ll w = 1; 
            for(j = 0; j < G.size(); ++j) 
            {
                w *= (1ll * (ll) (G[j].x ^ G[j].y)) % mod, w %= mod;    
            }     
            printf("%lld
    ", w);      
        }              
        return 0;     
    }
    

      

    卡常版: 

    #include <cstdio> 
    #include <algorithm>
    #include <cstring>    
    #include <vector> 
    #define N 200006
    #define ll long long   
    #define mod 1000000007        
    #define lson t[now].ls 
    #define rson t[now].rs 
    #define siz (t[now].v.size() - 1)
    #define setIO(s) freopen(s".in", "r" , stdin) , freopen(s".out", "w", stdout)     
    using namespace std;             
    namespace IO 
    {
        char *p1, *p2, buf[100000]; 
        #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
        int rd() {
        int x = 0;
        char  c = nc();
            while (c < 48) {
                c = nc();
            }
            while (c > 47) {
                x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
            }
            return x;
        } 
        char pbuf[100000],*pp=pbuf;
        void push(const char c) {
            if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf;
            *pp++=c;
        }
        void write(int x) {
            static int sta[35];
            int top=0;
            do{sta[top++]=x%10,x/=10;}while(x);
            while(top) push(sta[--top]+'0');
            push('
    ');
        }
    }
    int n ;           
    struct P 
    { 
        ll x , y;   
        P(ll x = 0, ll y = 0) : x(x), y(y) {}  
    }p[N]; 
    struct Node 
    {    
        int ls, rs ;          
        vector <P> v; 
    }t[N << 2];   
    vector <P> G, V, A;               
    inline void pushup(int L, int R, int now) 
    {     
        if(!rson) 
        {
            t[now].v = t[lson].v;        
        }
        else 
        {
            int p1 = 0, p2 = 0;      
            while(p1 < t[lson].v.size() && p2 < t[rson].v.size()) 
            { 
                if(t[lson].v[p1].x == t[rson].v[p2].x && t[lson].v[p1].y == t[rson].v[p2].y) ++p1, ++p2;   
                else if(t[lson].v[p1].x >= t[rson].v[p2].x && t[lson].v[p1].y >= t[rson].v[p2].y || t[lson].v[p1].x > t[rson].v[p2].x)    
                {          
                    if(t[now].v.empty() || t[lson].v[p1].y > t[now].v[t[now].v.size() - 1].y) 
                    {
                        t[now].v.push_back(t[lson].v[p1]);      
                    }           
                    ++ p1;         
                }     
                else if(t[rson].v[p2].x >= t[lson].v[p1].x && t[rson].v[p2].y >= t[lson].v[p1].y || t[rson].v[p2].x > t[lson].v[p1].x) 
                {
                    if(t[now].v.empty() || t[rson].v[p2].y > t[now].v[t[now].v.size() - 1].y) 
                    {
                        t[now].v.push_back(t[rson].v[p2]);    
                    } 
                    ++ p2; 
                }         
            }                  
            while(p1 < t[lson].v.size()) 
            {        
                if(t[now].v.empty() || (t[lson].v[p1].x <= t[now].v[siz].x && t[lson].v[p1].y > t[now].v[siz].y)) 
                    t[now].v.push_back(t[lson].v[p1]); 
                ++p1; 
            }
            while(p2 < t[rson].v.size()) 
            {
                if(t[now].v.empty() || (t[rson].v[p2].x <= t[now].v[siz].x && t[rson].v[p2].y > t[now].v[siz].y)) 
                    t[now].v.push_back(t[rson].v[p2]); 
                ++p2; 
            }
        }        
    }
    void build(int l, int r, int now) 
    { 
        if(l == r) 
        {      
            t[now].v.push_back(P(p[l].x, p[l].y));            
            return ;    
        } 
        int mid = (l + r) >> 1;        
        build(l, mid, now << 1), t[now].ls = now << 1; 
        if(r > mid)  build(mid + 1, r, now << 1 | 1), t[now].rs = now << 1 | 1;      
        pushup(l, r, now);             
    } 
    inline void query(int l, int r, int now, int L, int R) 
    {         
        if(l >= L && r <= R)  
        {     
            if(G.empty()) 
            {
                G = t[now].v;         
            }
            else 
            {          
                V = G, A = t[now].v;              
                G.clear();   
                // merge(V, A)     
                int p1 = 0, p2 = 0;      
                while(p1 < V.size() && p2 < A.size()) 
                { 
                    if(V[p1].x == A[p2].x && V[p1].y == A[p2].y) ++p1, ++p2; 
                    else if(V[p1].x >= A[p2].x && V[p1].y >= A[p2].y || V[p1].x > A[p2].x)    
                    {          
                        if(G.empty() || V[p1].y > G[G.size() - 1].y) 
                        {
                            G.push_back(V[p1]);      
                        }           
                        ++ p1;         
                    }     
                    else if(A[p2].x >= V[p1].x && A[p2].y >= V[p1].y || A[p2].x > V[p1].x) 
                    {
                        if(G.empty() || A[p2].y > G[G.size() - 1].y) 
                        {
                            G.push_back(A[p2]);    
                        } 
                        ++ p2; 
                    }          
                }    
                while(p1 < V.size()) 
                {
                    if(G.empty() || (V[p1].x <= G[G.size() - 1].x && V[p1].y > G[G.size() - 1].y)) 
                        G.push_back(V[p1]); 
                    ++p1; 
                }
                while(p2 < A.size()) 
                {
                    if(G.empty() || (A[p2].x <= G[G.size() - 1].x && A[p2].y > G[G.size() - 1].y)) 
                        G.push_back(A[p2]); 
                    ++p2; 
                }
            }   
            return; 
        } 
        int mid = (l + r) >> 1; 
        if(L <= mid) query(l, mid, now << 1, L, R);   
        if(R > mid) query(mid + 1, r, now << 1 | 1, L, R);    
    }
    int main() 
    { 
        // setIO("input"); 
        using namespace IO;      
        int i , j, q;  
        n = rd();   
        for(i = 1; i <= n ; ++i)
        {
            p[i].x = (ll) rd(); 
            p[i].y = (ll) rd();        
        }
        build(1, n, 1);          
        q = (ll) rd();   
        for(int cas = 1; cas <= q; ++cas) 
        {
            int l, r;  
            l = rd(), r = rd();    
            G.clear();   
            query(1, n, 1, l, r);    
            ll w = 1; 
            for(j = 0; j < G.size(); ++j) 
            {
                w *= (1ll * (ll) (G[j].x ^ G[j].y)) % mod, w %= mod;    
            }     
            write(w);   
        }            
        fwrite(pbuf,1,pp-pbuf,stdout);  
        return 0;     
    } 
    

      

  • 相关阅读:
    COGS 859. 数列
    9.7noip模拟试题
    hash练习
    9.6noip模拟试题
    9.5noip模拟试题
    poj 2117 Electricity
    洛谷P1993 小 K 的农场(查分约束)
    9.2noip模拟试题
    洛谷 P1273 有线电视网(dp)
    面试题收集
  • 原文地址:https://www.cnblogs.com/guangheli/p/11344603.html
Copyright © 2011-2022 走看看