BestCoder Round #29 1003 (hdu 5172) GTY's gay friends [线段树 判不同 预处理 好题]

 

传送门

GTY's gay friends


Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 264    Accepted Submission(s): 57


Problem Description
GTY has gay friends. To manage them conveniently, every morning he ordered all his gay friends to stand in a line. Every gay friend has a characteristic value i   , to express how manly or how girlish he is. You, as GTY's assistant, have to answer GTY's queries. In each of GTY's queries, GTY will give you a range [l,r . Because of GTY's strange hobbies, he wants there is a permutation [1..rl+1 in [l,r . You need to let him know if there is such a permutation or not.
 
Input
Multi test cases (about 3) . The first line contains two integers n and m ( 1n,m100000  ), indicating the number of GTY's gay friends and the number of GTY's queries. the second line contains n numbers seperated by spaces. The th   number i   ( 1 ) indicates GTY's th   gay friend's characteristic value. The next m lines describe GTY's queries. In each line there are two numbers l and r seperated by spaces ( 1lr ), indicating the query range.
 
Output
For each query, if there is a permutation [1..rl+1 in [l,r , print 'YES', else print 'NO'.
 
Sample Input
8 5 2 1 3 4 5 2 3 1 1 3 1 1 2 2 4 8 1 5 3 2 1 1 1 1 1 1 2
 
Sample Output
YES NO YES YES YES YES NO

 

转自官方题解:http://bestcoder.hdu.edu.cn/

1003 GTY's gay friends
一个区间是排列只需要区间和为len(len+1)2  

(le

为区间长度),且互不相同,对于第一个问题我们用前缀和解决,对于第二个问题,预处理每个数的上次出现位置,记它为pre,互不相同即区间中pre的最大值小于左端点,使用线段树或Sparse Table即可在O(n)/O(nlogn

的预处理后 O(logn)/O(1

回答每个询问.不过我们还有更简单的hash做法,对于[1..n

中的每一个数随机一个64位无符号整型作为它的hash值,一个集合的hash值为元素的异或和,预处理[1..n

的排列的hash和原序列的前缀hash异或和,就可以做到线性预处理,O(1

回答询问.

 

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cstdio>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<queue>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<string>
 12 
 13 #define N 1000005
 14 #define M 105
 15 #define mod 10000007
 16 //#define p 10000007
 17 #define mod2 1000000000
 18 #define ll long long
 19 #define LL long long
 20 #define eps 1e-6
 21 #define inf 100000000
 22 #define maxi(a,b) (a)>(b)? (a) : (b)
 23 #define mini(a,b) (a)<(b)? (a) : (b)
 24 
 25 using namespace std;
 26 
 27 ll n,m;
 28 ll a[N];
 29 ll f[N];
 30 ll pr[N];
 31 ll sum[N];
 32 
 33 ll mapre[4*N];
 34 
 35 ll build(ll i,ll l,ll r)
 36 {
 37     if(l==r){
 38         mapre[i]=pr[l];
 39         //printf(" i=%I64d l=%I64d mapre=%I64d pr=%I64d\n",i,l,mapre[i],pr[l]);
 40         return mapre[i];
 41     }
 42     ll mid=(l+r)/2;
 43     ll lm=build(2*i,l,mid);
 44     ll rm=build(2*i+1,mid+1,r);
 45     mapre[i]=max(lm,rm);
 46     //printf(" i=%I64d mapre=%I64d\n",i,mapre[i]);
 47     return mapre[i];
 48 }
 49 
 50 ll query(ll i,ll L,ll R,ll l,ll r)
 51 {
 52     if(l>=L && r<=R){
 53         return mapre[i];
 54     }
 55     ll mid=(l+r)/2;
 56     ll lm,rm;
 57     lm=0;rm=0;
 58     if(L<=mid){
 59         lm=query(i*2,L,R,l,mid);
 60     }
 61     if(R>mid){
 62         rm=query(i*2+1,L,R,mid+1,r);
 63     }
 64     return max(lm,rm);
 65 }
 66 
 67 void ini()
 68 {
 69     ll i;
 70     sum[0]=0;
 71     memset(f,0,sizeof(f));
 72     for(i=1;i<=n;i++){
 73         scanf("%I64d",&a[i]);
 74         sum[i]=sum[i-1]+a[i];
 75     }
 76     //for(i=0;i<=n;i++){
 77     //    printf(" i=%I64d sum=%I64d\n",i,sum[i]);
 78    // }
 79     for(i=1;i<=n;i++){
 80         pr[i]=f[ a[i] ];
 81         f[ a[i] ]=i;
 82     }
 83    // for(i=0;i<=n;i++){
 84    //     printf(" i=%I64d pr=%I64d\n",i,pr[i]);
 85    // }
 86     build(1,1,n);
 87 }
 88 
 89 void solve()
 90 {
 91     ll x,y;
 92     ll ss;
 93     ll len;
 94     ll qu;
 95     while(m--){
 96         scanf("%I64d%I64d",&x,&y);
 97         len=y-x+1;
 98         ss=sum[y]-sum[x-1];
 99         //printf(" ss=%I64d sum=%I64d\n",ss,len*(len+1)/2);
100         if(ss==(len*(len+1)/2)){
101             qu=query(1,x,y,1,n);
102             if(qu<x){
103                 printf("YES\n");
104             }
105             else{
106                 printf("NO\n");
107             }
108         }
109         else{
110             printf("NO\n");
111         }
112     }
113 }
114 
115 void out()
116 {
117 
118 }
119 
120 int main()
121 {
122     //freopen("data.in","r",stdin);
123     //freopen("data.out","w",stdout);
124     //scanf("%d",&T);
125     //for(int ccnt=1;ccnt<=T;ccnt++)
126    // while(T--)
127     //scanf("%d%d",&n,&m);
128     while(scanf("%I64d%I64d",&n,&m)!=EOF)
129     {
130         ini();
131         solve();
132         out();
133     }
134     return 0;
135 }

 

posted on 2015-02-08 16:55  njczy2010  阅读(364)  评论(0编辑  收藏  举报