HDU 5172 GTY's gay friends HASH随机算法

来源:互联网 发布:淘宝买东西怎么要发票 编辑:程序博客网 时间:2024/03/29 19:32

传送门:点击打开链接

GTY's gay friends

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


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 valueai , 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. Theith 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
 


Source
BestCoder Round #29

题意:给出一个长度为n的数组(n<=100W).每个数都<=100W。然后m次询问,每次询问l..r区间内是否为1..r-l+1的一个排列。

思路:对每个数生成一个无符号64bit随机数。可以求得1..x的随机值的异或和(用xor[i]表示1..i的异或和)。求得a[1..n]的异或和(用sum[i]表示从a[1]到a[i]的异或和)。对于每一个询问l,r,用前缀和的思想,可以求出a[l..r]的异或和。异或满足交换律,如果这个值和xor[r-l+1]相等的话,那么这个区间内就是一个1..r-l+1的排列。

代码:

#include<cstdio>#include<ctime>#include<cstdlib>#define uLL unsigned __int64#define maxn 1000005uLL XOR[maxn],sum[maxn],val[maxn];inline uLL RANDuLL(){    uLL one=1;    uLL RAND=(rand()+rand())*(one<<47)+(rand()+rand())*(one<<31)+(rand()+rand())*(one<<15)+(rand()+rand());    return RAND;}inline int getint(){    int c;    while (c = getchar(), c<'0' || '9'<c);    int res = c - 48;    while (c = getchar(), '0' <= c&&c <= '9') res = (res << 3) + res + res + c - 48;    return res;}int main(){    srand(time(NULL));    XOR[0]=0;    for(int i=1;i<maxn;i++)    {        val[i]=RANDuLL();        XOR[i]=XOR[i-1]^val[i];    }    int n,m;    while(~scanf("%d %d",&n,&m))    {        sum[0]=0;        for(int i=1;i<=n;i++)        {            int x;            x=getint();            sum[i]=val[x]^sum[i-1];        }        while(m--)        {            int l,r;            l=getint();            r=getint();            if(XOR[r-l+1]==(sum[r]^sum[l-1])) puts("YES");            else puts("NO");        }    }    return 0;}

极度优化的线段树也是能过的。姿势最重要

#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>using namespace std;typedef __int64 LL;#define NN 1000010struct node{    int l,r;    int id;}q[NN];bool cmp(node t1,node t2){    return t1.r<t2.r;}int mx[NN*3];LL sum[NN*3];void push_up(int id){    sum[id]=sum[id<<1]+sum[id<<1|1];    mx[id]=max(mx[id<<1],mx[id<<1|1]);}int MAX;LL SUM;void build(){    memset(mx,0,sizeof(mx));    memset(sum,0,sizeof(sum));}void update(int id,int L,int R,int pos,int val,int mxx){    if(L==R)    {        sum[id]=(LL)val;        mx[id]=mxx;        return ;    }    int mid=(L+R)>>1;;    if(pos<=mid)        update(id<<1,L,mid,pos,val,mxx);    else        update(id<<1|1,mid+1,R,pos,val,mxx);    push_up(id);}void query(int id,int L,int R,int l,int r){    if(l<=L&&R<=r)    {        MAX=max(MAX,mx[id]);        SUM+=sum[id];        return ;    }    int mid=(L+R)>>1;    if(l<=mid)        query(id<<1,L,mid,l,r);    if(mid<r)        query(id<<1|1,mid+1,R,l,r);}int a[NN],p[NN],pre[NN];inline int getint(){    int c;    while (c = getchar(), c<'0' || '9'<c);    int res = c - 48;    while (c = getchar(), '0' <= c&&c <= '9') res = (res << 3) + res + res + c - 48;    return res;}int main(){    int n,m;    while(scanf("%d %d",&n,&m)!=EOF)    {        for(int i=1;i<=n;i++) a[i]=getint();        for(int i=1;i<=m;i++)        {            q[i].l=getint();            q[i].r=getint();            q[i].id=i;        }        sort(q+1,q+m+1,cmp);        build();        memset(p,0,sizeof(p));        memset(pre,0,sizeof(pre));        for(int i=1;i<=n;i++)        {            pre[i]=p[a[i]];            p[a[i]]=i;        }        int t=1;        memset(p,0,sizeof(p));        for(int i=1;i<=n;i++)        {            update(1,1,n,i,a[i],pre[i]);            while(i==q[t].r)            {                SUM=0;                MAX=0;                LL tt=(LL)(q[t].r-q[t].l+1);                //printf("%d %d  %d??\n",q[t].l,q[t].r,q[t].id);                LL sum=tt*(tt+1)/2;                query(1,1,n,q[t].l,q[t].r);                //printf("%I64d %d   %I64d  %d\n",tmp.sum,tmp.mx ,sum,q[t].l);                if(sum==SUM && MAX < q[t].l)                {                    p[q[t].id]=1;                }                ++t;            }        }        for(int i=1;i<=m;i++)        {            if(p[i]==1)                puts("YES");            else puts("NO");        }    }    return 0;}



0 0