您的位置:首页 > 其它

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

2015-02-08 16:55 281 查看
传送门

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)

回答询问.


#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<string>

#define N 1000005
#define M 105
#define mod 10000007
//#define p 10000007
#define mod2 1000000000
#define ll long long
#define LL long long
#define eps 1e-6
#define inf 100000000
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b)

using namespace std;

ll n,m;
ll a
;
ll f
;
ll pr
;
ll sum
;

ll mapre[4*N];

ll build(ll i,ll l,ll r)
{
if(l==r){
mapre[i]=pr[l];
//printf(" i=%I64d l=%I64d mapre=%I64d pr=%I64d\n",i,l,mapre[i],pr[l]);
return mapre[i];
}
ll mid=(l+r)/2;
ll lm=build(2*i,l,mid);
ll rm=build(2*i+1,mid+1,r);
mapre[i]=max(lm,rm);
//printf(" i=%I64d mapre=%I64d\n",i,mapre[i]);
return mapre[i];
}

ll query(ll i,ll L,ll R,ll l,ll r)
{
if(l>=L && r<=R){
return mapre[i];
}
ll mid=(l+r)/2;
ll lm,rm;
lm=0;rm=0;
if(L<=mid){
lm=query(i*2,L,R,l,mid);
}
if(R>mid){
rm=query(i*2+1,L,R,mid+1,r);
}
return max(lm,rm);
}

void ini()
{
ll i;
sum[0]=0;
memset(f,0,sizeof(f));
for(i=1;i<=n;i++){
scanf("%I64d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
//for(i=0;i<=n;i++){
//    printf(" i=%I64d sum=%I64d\n",i,sum[i]);
// }
for(i=1;i<=n;i++){
pr[i]=f[ a[i] ];
f[ a[i] ]=i;
}
// for(i=0;i<=n;i++){
//     printf(" i=%I64d pr=%I64d\n",i,pr[i]);
// }
build(1,1,n);
}

void solve()
{
ll x,y;
ll ss;
ll len;
ll qu;
while(m--){
scanf("%I64d%I64d",&x,&y);
len=y-x+1;
ss=sum[y]-sum[x-1];
//printf(" ss=%I64d sum=%I64d\n",ss,len*(len+1)/2);
if(ss==(len*(len+1)/2)){
qu=query(1,x,y,1,n);
if(qu<x){
printf("YES\n");
}
else{
printf("NO\n");
}
}
else{
printf("NO\n");
}
}
}

void out()
{

}

int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
//scanf("%d",&T);
//for(int ccnt=1;ccnt<=T;ccnt++)
// while(T--)
//scanf("%d%d",&n,&m);
while(scanf("%I64d%I64d",&n,&m)!=EOF)
{
ini();
solve();
out();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: