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 n
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 a 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..r−l+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 ( 1≤n,m≤100000
), 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 i th
number a i
( 1≤a i ≤n
) indicates GTY‘s i 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 ( 1≤l≤r≤n
), indicating the query range.
Output
For each query, if there is a permutation [1..r−l+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 (len 为区间长度),且互不相同,对于第一个问题我们用前缀和解决,对于第二个问题,预处理每个数的上次出现位置,记它为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 }
BestCoder Round #29 1003 (hdu 5172) GTY's gay friends [线段树 判不同 预处理 好题]