ZOJ Monthly, August 2012-A-ZOJ 3633 ZOJ 3635

来源:互联网 发布:python擅长做什么 编辑:程序博客网 时间:2024/05/01 22:44

题意:排列的玩具中,都有标号,给定区间,从右往左,首次出现重复,就行输出,没有则输出"YES"。


做法:要用的离线线段树,好吧,线段树会,离线却是个什么玩意?

           看了官方的解题报道,用的是树状数组,大部分情况下线段树可以改成树状数组(除了动态更新的题,比如有个题就是求区间的最高成绩就不能用树状数组了),树状数组做题很抽象的,,,(实力不济)

          幸好有map啊,有函数可以判断是否map中是否存在已经有的点了,如果有此数输出,如果没有则放入map;

</pre><pre code_snippet_id="247029" snippet_file_name="blog_20140320_1_9930508" name="code" class="cpp">


//Author£ºCY//School: CUST#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#include<cmath>#include<stdlib.h>#include<iomanip>#include<list>#include<deque>#include<map>#include <stdio.h>#define maxn 501000#define PI 3.1415926535897using namespace std;map<int ,int >gettimes;int a[maxn];int n,m;int l,r;int main(){    while(scanf("%d",&n)!=EOF){    int i,j,k;    for(i=1;i<=n;i++)        scanf("%d",&a[i]);    cin>>m;    while(m--){        gettimes.clear();//清空map        scanf("%d%d",&l,&r);        for(i=r;i>=l;i--){            if(!gettimes.count(a[i]))                 gettimes[a[i]]=1;//没有相同的            else                 break;       }        if(i<l)            printf("OK\n");        else            printf("%d\n",a[i]);       }        cout<<endl;    }    return 0;}
</pre><pre code_snippet_id="247029" snippet_file_name="blog_20140320_2_1598165" name="code" class="cpp">

ZOJ 3635  线段树的题目,最简单的线段树运用


题意:n个人选第几个空座,问第i个人坐在第几个空座。


做法:把每个人放进树里,然后返回他坐下的位置,进行保存。这个题和poj上的一个插队题很相像,不过那个题是从后往前放进树里。


//Author£ºCY//School: CUST#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#include<cmath>#include<stdlib.h>#include<iomanip>#include<list>#include<deque>#include<map>#include <stdio.h>#define maxn 50010#define LL(x) (x<<1)#define RR(x) ((x<<1)|1)#define PI 3.1415926535897using namespace std;int ip;struct tree{    int left;    int right;    int val;    int mid(){        return (left+right)>>1;     }}node[maxn<<2];int c[maxn][2];void build (int l ,int r,int rt){//建树     node[rt].left=l;     node[rt].right=r;     node[rt].val=r-l+1;     if(l==r)return;     int mid=node[rt].mid();     build(l,mid,LL(rt));     build(mid+1,r,RR(rt));}void  update(int l,int rt){     node[rt].val--;    if(node[rt].left==node[rt].right){            ip=node[rt].left;            return  ;    }    int mid=node[rt].mid();    if(l<=node[LL(rt)].val)        update(l,LL(rt));    else        update(l-node[LL(rt)].val,RR(rt));}int main(){    int n,m;    while(scanf("%d",&n)!=EOF)    {        memset(c,0,sizeof(c));        int i,j,k;        build(1,n,1);        int temp;        for(i=1;i<=n;i++)        {            scanf("%d",&temp);            update(temp,1);            c[i][1]=ip;//保存第i个人的位置        }        scanf("%d",&m);        for(i=1;i<m;i++){            scanf("%d",&temp);            printf("%d ",c[temp][1]);//不然要超时哦        }        scanf("%d",&temp);        cout<<c[temp][1]<<endl;    }    return 0;}




0 0
原创粉丝点击