hdu5286 wyh2000 and sequence 分块处理
来源:互联网 发布:网络舆论引导途径 编辑:程序博客网 时间:2024/05/19 02:43
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<vector>#include<map>using namespace std;const int maxn=51005;const int mod=1000000007;struct pi{ int sum; int lson; int rson;}pp[maxn*17];int root[maxn],tot;void build(int cnt,int l,int r){ pp[cnt].sum=0; if(l==r) return; pp[cnt].lson=tot+1; tot++; build(tot,l,(l+r)/2); pp[cnt].rson=tot+1; tot++; build(tot,(l+r)/2+1,r);}void merg(int qq,int cnt,int n,int p,int k){ int le,ri,mid; le=1; ri=n; while(le<=ri){ mid=(le+ri)/2; pp[cnt]=pp[qq]; pp[cnt].sum+=k; if (le==ri) break; if(p<=mid){ pp[cnt].lson=tot+1; tot++; ri=mid; cnt=tot; qq=pp[qq].lson; } else{ pp[cnt].rson=tot+1; tot++; le=mid+1; cnt=tot; qq=pp[qq].rson; } }}int query(int cnt,int le,int ri,int l,int r){ int s=0; int mid; if(le>=l&&ri<=r){ return pp[cnt].sum; } mid=(le+ri)/2; if(l<=mid) s+=query(pp[cnt].lson,le,mid,l,r); if(r>mid) s+=query(pp[cnt].rson,mid+1,ri,l,r); return s;}int a[maxn],b[maxn],c[maxn];int l[maxn],vis[maxn],r[505],le[505];int g[315][315];vector<int>gg[maxn],g1;//map<int ,int>mm[505];int d[maxn][300];int main(){ int i,j,n,m,t; cin>>t; while(t--){ scanf("%d%d",&n,&m); memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; gg[i].clear(); } sort(b+1,b+1+n); memset(d,0,sizeof(d)); for(i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+1+n,a[i])-b; vis[a[i]]++; } for(i=1;i<=n;i++){ long long q=1; gg[i].push_back(0); for(j=1;j<=vis[i];j++){ q=q*b[i]; q%=mod; gg[i].push_back(q); } } int p=sqrt(n),f=0; for(i=1;i<=n;i++){ f++; int q=min(i+p-1,n); r[f]=q; le[f]=i; for(j=1;j<=n;j++){ d[j][f]=d[j][f-1]; } for(j=i;j<=q;j++){ l[j]=f; d[a[j]][f]++; } i=q; } memset(g,0,sizeof(g)); for(i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); for(j=i;j<=n;j++){ vis[a[j]]++; if(j==i||l[j]!=l[j-1]){ g[l[i]][l[j]]=(g[l[i]][l[j]-1]+gg[a[j]][vis[a[j]]])%mod-gg[a[j]][vis[a[j]]-1]; g[l[i]][l[j]]%=mod; } else{ g[l[i]][l[j]]+=(gg[a[j]][vis[a[j]]]-gg[a[j]][vis[a[j]]-1])%mod; g[l[i]][l[j]]%=mod; } } i+=p-1; } memset(vis,0,sizeof(vis)); int la=0; for(i=0;i<m;i++){ int x,y,ll,rr; scanf("%d%d",&x,&y); ll=x; rr=y; x=min((ll^la)%n+1,(rr^la)%n+1); y=max((ll^la)%n+1,(rr^la)%n+1); g1.clear(); if(l[y]-l[x]<=1){ for(j=x;j<=y;j++){ if(vis[a[j]]==0) g1.push_back(a[j]); vis[a[j]]++; } int s=0; int p=g1.size(); for(j=0;j<p;j++){ s+=gg[g1[j]][vis[g1[j]]]; vis[g1[j]]=0; s%=mod; } s=(s+mod)%mod; printf("%d\n",s); la=s; } else{ int s=0; s=g[l[x]+1][l[y]-1]; for(j=x;j<=r[l[x]];j++){ if(!vis[a[j]]) g1.push_back(a[j]); vis[a[j]]++; } for(j=le[l[y]];j<=y;j++){ if(!vis[a[j]]) g1.push_back(a[j]); vis[a[j]]++; } int p=g1.size(); for(j=0;j<p;j++){ int v=g1[j]; int q=d[v][l[y]-1]-d[v][l[x]]; s+=(gg[v][q+vis[v]]-gg[v][q])%mod; s%=mod; vis[v]=0; } s=(s%mod+mod)%mod; printf("%d\n",s); la=s; } } }}
对于答案我们不好用线段树维护,但是n只有50000,所以我们可以用分块的方法,来处理
令f(l,r) 表示[l,r] 的答案。我们对于序列分块,对于第i 块,令Si 为第i 块的左端点。令g(a,b) 表示第a 块开头到第b 块末尾这一段序列的答案。下面我们讨论如何求g(a,b) 。我们枚举a ,再枚举j(Sa≤j≤n) ,考虑j 转移到j+1 ,f(Sa,j) 和f(Sa,j+1) 的关系。其中f(Sa,j+1)=f(Sa,j)−Asum(Aj+1)j+1+Asum(Aj+1)+1j+1 sum(x) 表示x 在区间[Sa,j] 中出现的次数,这样我们就能用nn‾‾√logn 的时间求出g(a,b) 。令h(i,j) 表示i 在前j 个块中出现的次数,这个也很容易用n‾‾√ 的时间求出。考虑询问[l,r] ,两端的我们可以暴力求出来,中间的块内答案可以直接用g 数组求出。然后我们可以用类似求g 数组的方法将两端的数加入中间的块内。复杂度O(Qn‾‾√logn) 。
但是问题来了,两端的怎么合并到中间,我们至少的知道中间块的元素个数,我们可以这样:对于每个数用一个数组维护每块及其之前这个数出现的次数,空间复杂度是nsqrt(n);算的时候直接暴力两端的时候可以用o(1)处理,至于次方我们可以用vector来预处理,这样总复杂度是nsqrt(n),提醒一下:如果用主席树求点个数的代码会T。
0 0
- hdu5286 wyh2000 and sequence 分块处理
- hdu5286 wyh2000 and sequence
- 【分块】 HDOJ 5286 wyh2000 and sequence
- hdu 5286 wyh2000 and sequence 分块
- Hdu 5286 wyh2000 and sequence(序列分块)
- HDU 5286 wyh2000 and sequence 分块,贡献,好题
- HDU 5057 Argestes and Sequence 分块
- wyh2000 and pupil
- hdu5285 wyh2000 and pupil
- wyh2000 and pupil
- HDU5285.wyh2000 and pupil
- [hdu5285]wyh2000 and pupil
- HDU 5057 Argestes and Sequence (离线树状数组 || 分块)
- HDU5057-Argestes and Sequence(分块&&树状数组)
- hdu 5285 wyh2000 and pupil
- HDU 5285 wyh2000 and pupil
- HDU 5285 wyh2000 and pupil
- HDU 5285:wyh2000 and pupil
- 杭电oj2201 熊猫阿波的故事题解
- Android ListView 重要属性介绍
- leetcode: Contains Duplicate
- java 以 yyyy-MM-dd hh:mm:ss 获取系统时间
- 动画特效五:灌水动画
- hdu5286 wyh2000 and sequence 分块处理
- hdu 3363 Ice-sugar Gourd
- java并发编程第四章 线程执行器(5)
- 视图翻转
- 字母重排
- java并发编程第四章 总结
- 拓撲排序學習
- 认识一下身边的互联网---经典互联网书籍阅读总结
- CentOS 7.0 VMware虚拟机 查找不到网卡 查找不到eth0