计蒜客 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\n", 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('\n');
    }
}
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;     
} 

  

转载于:https://www.cnblogs.com/guangheli/p/11344603.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值