GTY's gay friends

来源:互联网 发布:ug铣螺纹编程实例 编辑:程序博客网 时间:2024/04/23 23:49

题目链接

英文版

GTY's gay friends

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


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 ai , 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,m1000000 ), 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 ith number ai ( 1ain ) indicates GTY's ith 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 ( 1lrn ), 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 52 1 3 4 5 2 3 11 31 12 24 81 53 21 1 11 11 2
 

Sample Output
YESNOYESYESYESYESNO
 
英语版

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


问题描述
 GTY有n个基友,出于某种恶趣味,GTY每天早上会让他的基友们排成一行,每个基友有一个特征值,表示基友有多雄壮或娘炮,你,作为GTY的助手,必须回答GTY的每个询问,GTY每次会问一个区间[l,r]是否为一个1rl+1的排列。
输入描述
多组数据(约3组),每组数据的第一行有两个数n,m(1n,m100000) 表示初始基友数量和询问个数,第二行包含n个数ai(1ain)表示基友的特征值,接下来m行每行两个数l,r表示询问[l,r]是否为一个排列。
输出描述
对于每个询问,若它是一个排列,输出”YES”,否则输出”NO”
输入样例
8 52 1 3 4 5 2 3 11 31 12 24 81 53 21 1 11 11 2
输出样例
YESNOYESYESYESYESNO

/*一个区间是排列只需要区间和为len(len+1)2(len为区间长度),且互不相同,对于第一个问题我们用前缀和解决,对于第二个问题,预处理每个数的上次出现位置,记它为pre,互不相同即区间中pre的最大值小于左端点,使用线段树或Sparse Table.即可在O(n)/O(nlogn)的预处理后 O(logn)/O(1)回答每个询问.*/#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=1000000+10;int n,m,x,y;int sum[maxn<<2],t,pre[maxn],anx[maxn];__int64 S[maxn];void pushup(int rt) {    sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt) {    if(l==r) {        sum[rt]=pre[l];        // printf("[%d]\n",l);        return;    }    int mid=(l+r)>>1;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    pushup(rt);}int query(int L,int R,int l,int r,int rt) {    if(L<=l&&r<=R) {        return sum[rt];    }    int mid=(l+r)>>1;    int ret=0;    if(L<=mid) {        ret=max(ret,query(L,R,l,mid,rt<<1));    }    if(R>mid) {        ret=max(ret,query(L,R,mid+1,r,rt<<1|1));    }    return ret;}int main() {    //freopen("D://imput.txt","r",stdin);    while(~scanf("%d%d",&n,&m)) {        S[0]=0;        memset(anx,0,sizeof(anx));        for(int i=1; i<=n; i++) {            scanf("%d",&t);            pre[i]=anx[t];            anx[t]=i;            S[i]=S[i-1]+t;        }        build(1,n,1);        while(m--) {            scanf("%d%d",&x,&y);            int len = y-x+1;            __int64 res=(__int64)len*(len+1);            if(S[y]-S[x-1]!=res/2LL) {                printf("NO\n");            } else {                int t=query(x,y,1,n,1);                printf("%s\n",t<x?"YES":"NO");//互不相同即区间中pre的最大值小于左端点,            }        }    }    return 0;}


方法二:

/*一个集合的hash值为元素的异或和,预处理[1..n]的排列的hash和原序列的前缀hash异或和,就可以做到线性预处理,O(1)回答询问.*/#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <ctime>#include <algorithm>using namespace std;const int maxn=1000000+5;typedef __int64 LL;int n,m,t,l,r;LL Hash[maxn],xr[maxn],xt[maxn],Xor[maxn],Sxt[maxn];int main() {    srand(time(0));    for(int i=1; i<maxn; i++) {        Hash[i]=(LL)rand()*rand();        xr[i]=xr[i-1]^Hash[i];        xt[i]=xt[i-1]+i;    }    while(~scanf("%d%d",&n,&m)) {        memset(Sxt,0,sizeof(Sxt));        memset(Xor,0,sizeof(Xor));        for(int i=1; i<=n; i++) {            scanf("%d",&t);            Sxt[i]=Sxt[i-1]+t;            Xor[i]=Xor[i-1]^Hash[t];        }        while(m--) {            scanf("%d%d",&l,&r);            if(Sxt[r]-Sxt[l-1]==xt[r-l+1]&&(Xor[r]^Xor[l-1])==xr[r-l+1]) {                printf("YES\n");            } else {                printf("NO\n");            }        }    }    return 0;}


0 0
原创粉丝点击