zoukankan      html  css  js  c++  java
  • BZOJ 3524 [POI2014] Couriers/洛谷3567(可持久化线段树)

    题意:给你n个数,有m次询问,问你有没有[l,r]区间内有一个出现的次数大于等于区间长度的一半

    思路:主席树的节点y代表1到y,然后减去左端点x就得到的是区间[x,y]的信息,这样我们判断权值线段树上的左侧还是右侧大于k次,如果存在的话我们就一项向下找,找到子节点,看子节点是不是大于等于k次,如果是就存在,不是就返回0

    代码:(新离散化板子)

    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <math.h>
    #include <vector>
    #include <string>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <algorithm>
    #define zero(a) fabs(a)<eps
    #define max( x, y )  ( ((x) > (y)) ? (x) : (y) )
    #define min( x, y )  ( ((x) < (y)) ? (x) : (y) )
    #define lowbit(x) (x&(-x))
    #define debug(a) cerr<<#a<<"=="<<a<<endl
    typedef long long LL;
    const double pi=acos(-1.0);
    const double eps=1e-8;
    const int inf=0x3f3f3f3f;
    const LL linf=0x3f3f3f3f3f3f3f3f;
    using namespace std;
    
    const int maxn=500000+7;
    int n,m,a[maxn],root[maxn],cnt,x,y,k,sa[maxn],tot;
    struct node
    {
        int l,r,sum;
    }T[maxn*40];
    vector<int>v;
    int getid(int x)
    {
        return lower_bound(sa+1,sa+tot+1,x)-sa;
    }
    void update(int l,int r,int &x,int y,int pos)
    {
        T[++cnt]=T[y],T[cnt].sum++,x=cnt;
        if(l==r)return ;
        int mid=(l+r)>>1;
        if(pos<=mid)update(l,mid,T[x].l,T[y].l,pos);
        else update(mid+1,r,T[x].r,T[y].r,pos);
    }
    
    int query(int l,int r,int x,int y,int k)
    {
        if(l==r)return l;
        int mid=(l+r)>>1;
        int lans=T[T[y].l].sum-T[T[x].l].sum,rans=T[T[y].r].sum-T[T[x].r].sum;
        if(lans>=k)query(l,mid,T[x].l,T[y].l,k);
        else if(rans>=k)query(mid+1,r,T[x].r,T[y].r,k);
        else return 0;
    }
    
    int main()
    {
        cnt=0,tot=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sa[i]=a[i];
        }
        sort(sa+1,sa+n+1);
        tot=unique(sa+1,sa+1+n)-sa-1;
        for(int i=1;i<=n;i++){
            update(1,tot,root[i],root[i-1],getid(a[i]));
        }
    //    printf("fuck %d
    ",tot);
        while(m--){
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            int ans=query(1,tot,root[t1-1],root[t2],(t2-t1+1)/2+1);
    //        printf("test %d
    ",ans);
            printf("%d
    ",sa[ans]);
        }
        return 0;
    }
  • 相关阅读:
    项目选题报告答辩总结
    项目UML设计(团队)
    项目选题报告答辩总结
    第七次作业
    结对第二次
    第四次作业
    alpha冲刺4
    alpha冲刺3
    alpha冲刺2
    alpha冲刺1
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/8857723.html
Copyright © 2011-2022 走看看