zoukankan      html  css  js  c++  java
  • CF1000F One Occurrence 主席树 线段树

    题意:

    给定一个长度为n序列,m个询问,每次询问给定一个区间[l,r],如果这个区间里存在只出现一次的数,输出这个数(如果有多个就输出任意一个),没有就输出0,n,m<=5*10^5

    题解:

    •  考虑每个查询区间  维护数字上一个出现的位置 如果上一个出现的位置小于l 那么说明区间内只有一个数
    • 但是如果区间有两个相同的数字 可能左边的数字的上一个数字小于l   所以要消去其影响
    • 所以只要维护每个数字最右边数字的上一个数字出现的位置即可 可以在线用主席树来维护一个前缀和树  或者离线用线段树
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=5e5+10;
    struct node{int minn,num;}t[N<<6];
    node merge(node a,node b)
    {
        if(a.minn<b.minn)return (node){a.minn,a.num};
        else return (node){b.minn,b.num};
    }
    int lson[N<<6],rson[N<<6],n,m,last[N],pos[N],a[N],T[N],ncnt;
    void build(int l,int r,int &pos)
    {
        pos=++ncnt;
        if(l==r){t[pos]=(node){1000000000,0};return ;}
        int m=(l+r)>>1;
        build(l,m,lson[pos]);build(m+1,r,rson[pos]);
        t[pos]=merge(t[lson[pos]],t[rson[pos]]);
    }
    void upnode(int x,int v,int num,int l,int r,int pre,int &pos)
    {
        pos=++ncnt;
        lson[pos]=lson[pre];
        rson[pos]=rson[pre];
        t[pos]=t[pre];
        if(l==r){t[pos]=(node){v,num};return ;}
        int m=(l+r)>>1;
        if(x<=m)upnode(x,v,num,l,m,lson[pre],lson[pos]);
        else upnode(x,v,num,m+1,r,rson[pre],rson[pos]);
        t[pos]=merge(t[lson[pos]],t[rson[pos]]);
    }
    node qmin(int L,int R,int l,int r,int pos)
    {
        if(L<=l&&r<=R)return t[pos];
        node ans=(node){100000000,0};
        int m=(l+r)>>1;
        if(L<=m)ans=merge(ans,qmin(L,R,l,m,lson[pos]));
        if(R>m) ans=merge(ans,qmin(L,R,m+1,r,rson[pos]));
        return ans;
    }
    int main()
    {
        cin>>n;node ans;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            last[i]=pos[a[i]];
            pos[a[i]]=i;
        }
        build(1,n,T[0]);
        for(int i=1;i<=n;i++)
        {    
            T[i]=T[i-1];
            upnode(i,last[i],a[i],1,n,T[i],T[i]);
            if(last[i])    
            {
                upnode(last[i],100000000,0,1,n,T[i],T[i]);
            }
        }
        cin>>m;int l,r;
        while(m--)
        {
            scanf("%d%d",&l,&r);
            ans=qmin(l,r,1,n,T[r]);
            if(ans.minn<l)printf("%d
    ",ans.num);
            else printf("0
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    B/S实现大文件上传
    csharp实现大文件上传
    C#实现大文件上传
    h5批量下载文件
    association 的使用
    简单的MD5查询工具
    struts开发&lt;struts中的參数传递.三&gt;
    (转)SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源)
    (转)SQL SERVER的锁机制(一)——概述(锁的种类与范围)
    (转)SQL Server 中的事务和锁(三)-Range S-U,X-X 以及死锁
  • 原文地址:https://www.cnblogs.com/bxd123/p/11697536.html
Copyright © 2011-2022 走看看