HDU 5172 GTY's gay friends(HASH 随机算法)
来源:互联网 发布:盛势网络剧什么时候播 编辑:程序博客网 时间:2024/04/27 07:23
【题意】给出一个长度为n的数组(n<=100W).每个数都<=100W。然后m次询问,每次询问l..r区间内是否为1..r-l+1的一个排列
【解题方法】一个区间是排列只需要区间和为2len(len+1)(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)回答询问.
【AC 代码】
<span style="font-family:Arial;">//Hash 算法</span>#include <time.h>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn=1000010;#define uLL unsigned __int64uLL XOR[maxn],a[maxn],sum[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;}int main(){ srand(time(NULL)); XOR[0]=0; for(int i=1; i<maxn; i++){ a[i]=RANDuLL(); XOR[i]=XOR[i-1]^a[i]; } int n,m; while(scanf("%d%d",&n,&m)!=EOF) { sum[0]=0; int x; for(int i=1; i<=n; i++){ scanf("%d",&x); sum[i]=a[x]^sum[i-1]; } int l,r; while(m--){ scanf("%d%d",&l,&r); if(XOR[r-l+1]==(sum[r]^sum[l-1])){ puts("YES"); }else{ puts("NO"); } } }}
【线段树版本】
<span style="font-family:Arial;">//代码来自上决</span><pre name="code" class="cpp">#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> using namespace std; typedef __int64 LL; #define NN 1000010 struct 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
- HDU 5172 GTY's gay friends(HASH 随机算法)
- hdu 5172 GTY's gay friends Hash随机算法
- HDU 5172 GTY's gay friends HASH随机算法
- hdu 5172 GTY's gay friends (线段树||hash)
- Hdu 5172 GTY's gay friends
- hdu 5172 GTY's gay friends
- HDU 5172 GTY's gay friends
- HDU 5172 GTY's gay friends
- HDU 5172 GTY's gay friends(线段树)
- HDU 5172 GTY's gay friends (预处理+线段树)
- hdu 5172 GTY's gay friends (区间最值)
- HDU 5172 GTY's gay friends(线段树)
- hdu 5172 GTY's gay friends 线段树
- HDU 5172 - GTY's gay friends (线段树)
- HDU 5172 GTY's gay friends (线段树)
- HDU-5172-GTY's gay friends-线段树单点更新
- GTY's gay friends
- HDOJ 题目5172 GTY's gay friends(线段树)
- 个人技术网站收藏
- 【源码解读】EventBus3.0注册过程及事件分发源码分析
- 使用js进行防止重复提交
- 类和对象(游戏)
- Android网络连接之HttpURLConnection和HttpClient
- HDU 5172 GTY's gay friends(HASH 随机算法)
- Dollar toolbox 学习笔记(一)
- 51nod oj 1183 编辑距离 【求一个字符串到另一个字符串的最小操作次数【类似LCS】】
- Linux中configure/makefile的用法实例(附代码)
- UVA 11235-Frequent values(RMQ)
- 自定义ViewGroup ondraw方法不被调用解决办法
- C语言之指针 初习
- Windows钩子的使用
- 特殊符号大全分享给大家,直接复制粘贴就可以使用了!