BZOJ3207:花神的嘲諷計劃
阿新 • • 發佈:2018-11-17
tdi pac bzoj3 include || etc con man main
淺談主席樹:https://www.cnblogs.com/AKMer/p/9956734.html
題目傳送門:https://www.lydsy.com/JudgeOnline/problem.php?id=3207
每\(k\)位\(hash\)一下,然後直接找區間內有沒有\(hash\)值。
時間復雜度:\(O(mlogn)\)
空間復雜度:\(O(nlogn)\)
代碼如下:
#include <map> #include <cstdio> using namespace std; const int maxn=1e5+5,base=2333; map<int,int>s; int n,m,k,bin=1,id; int rt[maxn],p[maxn],a[maxn]; int read() { int x=0,f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0'; return x*f; } struct tree_node { int cnt,ls,rs; }; struct chairman_tree{ int tot; tree_node tree[maxn*18]; void ins(int lst,int &now,int l,int r,int pos) { now=++tot;tree[now]=tree[lst]; tree[now].cnt++; if(l==r)return; int mid=(l+r)>>1; if(pos<=mid)ins(tree[lst].ls,tree[now].ls,l,mid,pos); else ins(tree[lst].rs,tree[now].rs,mid+1,r,pos); } bool query(int lst,int now,int l,int r,int pos) { if(l==r)return tree[now].cnt-tree[lst].cnt>0; int mid=(l+r)>>1; if(pos<=mid)return query(tree[lst].ls,tree[now].ls,l,mid,pos); return query(tree[lst].rs,tree[now].rs,mid+1,r,pos); } }T; int main() { n=read(),m=read(),k=read(); for(int i=1;i<=k;i++)bin*=base; for(int i=1;i<=n;i++) { int x=read(); p[i]=p[i-1]*base+x; } for(int i=1;i<=n-k+1;i++) { int tmp=p[i+k-1]-p[i-1]*bin; if(!s[tmp])s[tmp]=++id; a[i]=s[tmp]; } for(int i=1;i<=n;i++) T.ins(rt[i-1],rt[i],1,id,a[i]); for(int i=1;i<=m;i++) { int x=read(),y=read(),tmp=0; for(int j=1;j<=k;j++) { int v=read(); tmp=tmp*base+v; } if(y-x+1<k||s[tmp]==0)puts("Yes"); else if(T.query(rt[x-1],rt[y-k+1],1,id,s[tmp]))puts("No"); else puts("Yes"); } return 0; }
BZOJ3207:花神的嘲諷計劃