• zoj 3633 Alice's present


    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3633

    两种解法:

    自己的解法是,因为当时考虑到开visit数组10的31方太大了,所以首先将给定的数离散化,然后对于在范围内的每一个数和他所在的数组中的下标连边。

    询问的时候,遍历查询范围,对于每一个数,如果这个数所连的边中下标有在这个数之前且在查询范围内的那么输出这个数就可以了。

    **********开始的时候ok搞成了小写,wa到吐血。。。。

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<stdio.h>
    #include<stdlib.h>
    #define maxn 500100
    using namespace std;
    struct node0
    {
     long long key;
     int id;
    }node[maxn];
    vector<int>line[maxn];
    int n;
    int m;
    long long  number[maxn];
    bool cmp1(struct node0 a,struct node0 b)
    {
     return a.key<b.key;
    }
    bool cmp2(struct node0 a,struct node0 b)
    {
     return a.id<b.id;
    }
    int main()
    {
        long long max;
     while(cin>>n)
     {
         memset(number,0,sizeof(number));
         memset(node,0,sizeof(node));
         for(int i=0;i<=n;i++)
         line[i].clear();
      for(int i=0;i<n;i++)
      {
       cin>>node[i].key;
       number[i]=node[i].key;
                     node[i].id=i;
      }
      sort(node,node+n,cmp1);//按照从小大大排序
    //离散化 int temp=node[0].key; node[0].key=0; line[0].push_back(node[0].id); for(int i=1;i<n;i++) { if(node[i].key==temp) node[i].key=node[i-1].key,line[node[i].key].push_back(node[i].id);//连边 else temp=node[i].key,node[i].key=node[i-1].key+1,line[node[i].key].push_back(node[i].id);//连边 } sort(node,node+n,cmp2);//按照下标排序。 cin>>m; while(m--) { int st,en; int flage=0; cin>>st>>en; int id; for(int i=en-1;i>=st-1;i--) { for(int j=0;j<line[node[i].key].size();j++) { if(line[node[i].key][j]>=i+1&&line[node[i].key][j]<=en-1)//访问 if(line[node[i].key][j]!=i) { flage=1;id=i;break; } } if(flage)break; } if(flage) cout<<number[id]<<endl; else cout<<"OK"<<endl; } cout<<endl; } return 0; }

      网上流传的做法是线段树,想了下也是,自己当时没有想到,对于每一个取得在这个数之前的和他相等的那个数的下标。在线段树中加入maxd属性,表示的是当前区间的所有数中,有一个数,和这个数的相等的且在这个数之前的那个下标比该区间的其他数的这个属性都大。

         然后就可以了,要判断返回的下标是不是在区间内

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include <vector>
    #include<map>
    #define maxn 500100
    using namespace std;
    int visit[100];
    struct node0
    {
       int  l;
       int  r;
       int  maxd;
    }node[maxn];
    int dis[maxn];
    int number[maxn];
    void build(int root,int l,int r)
    {
       node[root].l=l;
       node[root].r=r;
       if(l==r)
       {
        node[root].maxd=dis[l];
        return ;
       }
       int mid=(l+r)>>1;
       build(root<<1,l,mid);
       build(root<<1|1,mid+1,r);
       node[root].maxd=max(node[root<<1].maxd,node[root<<1|1].maxd);
       return ;
    }
    int query(int root,int l,int r)
    {
      //cout<<root<<" "<<node[root].l<<" "<<node[root].r<<" "<<node[root].maxd<<endl;
     if(node[root].l==l&&node[root].r==r)
     return node[root].maxd;
     //if(l==r)return 0;
     int mid=(node[root].l+node[root].r)>>1;
     if(r<=mid)
            return query(root<<1,l,r);
     else
            if(l>mid)
            return query(root<<1|1,l,r);
     else
     {
            return max(query(root<<1,l,mid),query(root<<1|1,mid+1,r));
     }
    }
    void output(int root)
    {
        if(!visit[root]);
        cout<<node[root].l<<" "<<node[root].r<<" "<<node[root].maxd<<" "<<root<<endl;;
        visit[root]=1;
        if(node[root].l==node[root].r)return ;
        output(root<<1);
        output(root<<1|1);
    }
    int main()
    {
       int n,m;
       int st,en;
       while(cin>>n)
       {
        map<long long,int>v;
        for(int i=1;i<=n;i++)
        {
         cin>>number[i];
         dis[i]=v[number[i]];
         v[number[i]]=i;
        }
        build(1,1,n);
       // output(1);
        cin>>m;
        while(m--)
        {
        cin>>st>>en;
        int  temp=query(1,st,en);
        if(temp>=st&&temp<=en)
         cout<<number[temp]<<endl;
        else
         cout<<"ok"<<endl;
        }
        cout<<endl;
       }
       return 0;
    }

    线段树的还是比自己的要快

  • 相关阅读:
    iOS 语录
    接口的理解
    android中src和background区别
    onItemClick 参数解释
    工作空间项目不存在,eclipse中项目删不掉
    [转载] IIS来搭建一个只能实现基本功能的FTP服务器
    [转]C# FTP操作类
    [转] VS2017 打包安装程序
    笔记本睿频的关闭与开启 [转载]
    C# 线程:定时器的使用
  • 原文地址:https://www.cnblogs.com/cs1003/p/2657910.html
Copyright © 2020-2023  润新知