zoukankan      html  css  js  c++  java
  • bzoj 3207 可持久化线段树

      首先因为固定询问长度,所以我们可以将整个长度为n的数列hash成长度为n-k+1的数列,每次询问的序列也hash成一个数,然后询问这个数是不是在某个区间中出现过,这样我们可以根据初始数列的权值建立可持久化线段树,对于每个询问先二分判断是否出现在数列中过,然后再判断是否在区间内出现过。也可以离线将询问和数列建立可持久化线段树,那么直接判断就可以了,但是空间消耗会大些。

      反思:偷懒直接用的map判的是否出现,然后改了hash用long long存之后map_insert没有改,然后就一直WA。

         不知道数据的范围,开大了数组好多。

    /**************************************************************
        Problem: 3207
        User: BLADEVIL
        Language: C++
        Result: Accepted
        Time:6580 ms
        Memory:130804 kb
    ****************************************************************/
     
    //By BLADEVIL
    #include <map>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define maxn 500010
    #define LL long long
      
    using namespace std;
       
    struct segment {
        int left,right,cnt;
        int son[2];
        segment() {
            left=right=cnt=0;
            memset(son,0,sizeof son);
        }
    }t[12*maxn];
       
    struct rec {
        int num,key;
        LL hash;
        rec() {
            hash=num=key=0;
        }
    }a[maxn];
       
    int n,m,k,sum,tot;
    int rot[maxn];
    map<LL,int>tree;
       
    bool cmp1(rec x,rec y) {
        return x.hash<y.hash;
    }
       
    bool cmp2(rec x,rec y) {
        return x.num<y.num;
    }
       
    void map_insert(LL x,int y) {
        if (tree.find(x)==tree.end()) tree.insert(pair<LL,int>(x,y));
    }
       
    void build(int &x,int l,int r) {
        if (!x) x=++tot;
        t[x].left=l; t[x].right=r;
        if (l==r) return ;
        int mid=t[x].left+t[x].right>>1;
        build(t[x].son[0],l,mid); build(t[x].son[1],mid+1,r);
    }
       
    void insert(int &x,int rot,int y) {
        if (!x) x=++tot;
        t[x].left=t[rot].left; t[x].right=t[rot].right;
        if (t[x].left==t[x].right) {
            t[x].cnt=t[rot].cnt+1;
            return ;
        }
        int mid=t[x].left+t[x].right>>1;
        if (y>mid) {
            t[x].son[0]=t[rot].son[0];
            insert(t[x].son[1],t[rot].son[1],y);
        } else {
            t[x].son[1]=t[rot].son[1];
            insert(t[x].son[0],t[rot].son[0],y);
        }
        t[x].cnt=t[rot].cnt+1;
    }
       
    int query(int lx,int rx,int y) {
        if (t[lx].left==t[lx].right) return t[rx].cnt-t[lx].cnt;
        int mid=t[lx].left+t[lx].right>>1;
        if (y>mid) return query(t[lx].son[1],t[rx].son[1],y); else return query(t[lx].son[0],t[rx].son[0],y);
    }
       
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=n;i++) scanf("%d",&a[i].key);
        n=n-k+1;
        for (int i=1;i<=n;i++) 
            for (int j=i;j<=i+k-1;j++) a[i].hash=a[i].hash*107+a[j].key;
        for (int i=1;i<=n;i++) a[i].num=i;
        sort(a+1,a+n+1,cmp1); sum=1; LL cur=a[1].hash;
        //for (int i=1;i<=n;i++) printf("%d ",a[i].hash); printf("
    ");
        for (int i=1;i<=n;i++)
            if (a[i].hash==cur) a[i].key=sum; else cur=a[i].hash,a[i].key=++sum;
        sort(a+1,a+n+1,cmp2);
        //for (int i=1;i<=n;i++) printf("%d ",a[i].key); printf("
    "); 
        for (int i=1;i<=n;i++) map_insert(a[i].hash,a[i].key);
        build(rot[0],1,sum);
        for (int i=1;i<=n;i++) insert(rot[i],rot[i-1],a[i].key);
        while (m--) {
            int l,r; scanf("%d%d",&l,&r); if (r>n) r=n;
            LL ha=0;
            for (int i=1;i<=k;i++) {
                int x; scanf("%d",&x);
                ha=ha*107+x;
            }
            map<LL,int>::iterator p=tree.find(ha);
            if (p==tree.end()) {
                printf("Yes
    ");
                continue;
            }
            int y=p->second;
            if (query(rot[l-1],rot[r],y)>0) printf("No
    "); else printf("Yes
    ");
            //printf("%d
    ",query(rot[l-1],rot[r],y));
        }
        return 0;
    }
  • 相关阅读:
    在报表中录入数据时如何实现行列转换
    CNN卷积神经网络代码实现【基于Python,Tensorflow】
    Spark Word2Vec算法代码实现
    Spark ML逻辑回归
    SolrCloud搜索引擎集群搭建【伪分布式、完全分布式】
    Scala之List,Set及Map基本操作
    bs4爬虫入门
    Scrapy爬虫入门
    Solr参数详解【Web客户端,DIH数据导入】
    Python多态
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3672384.html
Copyright © 2011-2022 走看看