紫书训练 7.17

it2022-05-05  117

https://vjudge.net/contest/311900#overview 树状数组+主席数

密码996996 

A - HH的项链

先按r排序,然后每次清除该数前面已经出现的位置,增加它新出现的位置。然后查询。

#include<bits/stdc++.h> #define il inline #define pb push_back #define fi first #define se second #define ms(_data,v) memset(_data,v,sizeof(_data)) #define sc(n) scanf("%d",&n) #define SC(n,m) scanf("%d %d",&n,&m) #define SZ(a) int((a).size()) #define rep(i,a,b) for(int i=a;i<=b;++i) #define drep(i,a,b) for(int i=a;i>=b;--i) using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-9; const int maxn=5e4+5; const int maxm=1e6+5; int a[maxn],sum[maxm],pre[maxm],ans[maxn<<2],n,m; struct node{ int l,r,id; }q[maxn<<2]; bool cmp(node x,node y){ return x.r<y.r; } void add(int p,int x){ while(p<=n) sum[p]+=x,p+=p&-p; } int ask(int p){ int res=0; while(p) res+=sum[p],p-=p&-p; return res; } int main(){ sc(n); rep(i,1,n) sc(a[i]); sc(m); rep(i,1,m){ SC(q[i].l,q[i].r); q[i].id=i; } sort(q+1,q+m+1,cmp); rep(i,1,m){ rep(j,q[i-1].r+1,q[i].r){ if(pre[a[j]]) add(pre[a[j]],-1); pre[a[j]]=j,add(pre[a[j]],1); } ans[q[i].id]=ask(q[i].r)-ask(q[i].l-1); } rep(i,1,m) printf("%d\n",ans[i]); return 0; }

B - K-th Number

主席数模板题

#include<cstdio> #include<iostream> #include<algorithm> #include<string> #include<cstring> #include<queue> #include<stack> #include<map> #include<set> #include<cmath> #include<sstream> //#include<bits/stdc++.h> #define il inline #define pb push_back #define fi first #define se second #define ms(_data,v) memset(_data,v,sizeof(_data)) #define sc(n) scanf("%d",&n) #define SC(n,m) scanf("%d %d",&n,&m) #define SZ(a) int((a).size()) #define rep(i,a,b) for(int i=a;i<=b;++i) #define drep(i,a,b) for(int i=a;i>=b;--i) using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-9; const int maxn=1e5+5; int a[maxn],b[maxn],rt[maxn*20],ls[maxn*20],rs[maxn*20],sum[maxn*20]; int n,m,tot; void build(int &rt,int l,int r){ rt=++tot; sum[rt]=0; if(l==r) return; int mid=(l+r)>>1; build(ls[rt],l,mid); build(rs[rt],mid+1,r); } void update(int &rt,int l,int r,int last,int p){ rt=++tot; ls[rt]=ls[last],rs[rt]=rs[last]; sum[rt]=sum[last]+1; if(l==r) return; int mid=(l+r)>>1; if(p<=mid) update(ls[rt],l,mid,ls[last],p); else update(rs[rt],mid+1,r,rs[last],p); } int query(int ss,int ee,int l,int r,int k){ if(l==r) return l; int mid=(l+r)>>1; int cnt=sum[ls[ee]]-sum[ls[ss]]; if(k<=cnt) return query(ls[ss],ls[ee],l,mid,k); else return query(rs[ss],rs[ee],mid+1,r,k-cnt); } int main(){ SC(n,m); rep(i,1,n) sc(a[i]),b[i]=a[i]; sort(b+1,b+n+1); int sz=unique(b+1,b+n+1)-(b+1); build(rt[0],1,sz); rep(i,1,n){ a[i]=lower_bound(b+1,b+sz+1,a[i])-b; update(rt[i],1,sz,rt[i-1],a[i]); } int l,r,k; rep(i,1,m){ sc(l),sc(r),sc(k); int id=query(rt[l-1],rt[r],1,sz,k); printf("%d\n",b[id]); } return 0; }

C - Dynamic Rankings

 待修改的主席数,俺也是才学。过了luogu上的这道题,但是这个一直段错误,难受,不知道原因。

#include<bits/stdc++.h> #define il inline #define pb push_back #define fi first #define se second #define ms(_data,v) memset(_data,v,sizeof(_data)) #define sc(n) scanf("%d",&n) #define SC(n,m) scanf("%d %d",&n,&m) #define SZ(a) int((a).size()) #define rep(i,a,b) for(int i=a;i<=b;++i) #define drep(i,a,b) for(int i=a;i>=b;--i) using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-9; const int maxn=1e5+5; unordered_map<int,int> rk; int T,n,m,tot,sz,a[maxn],b[maxn*5]; struct tree{ int l,r,x; }t[maxn*900]; int root[maxn],root1[maxn],cnt,tot1,tot2,q1[maxn],q2[maxn]; il int update(int l,int r,int last,int k,int op){ int rt=++cnt; t[rt]=t[last],t[rt].x+=op; if(l==r) return rt; int mid=(l+r)>>1; if(k<=mid) t[rt].l=update(l,mid,t[last].l,k,op); else t[rt].r=update(mid+1,r,t[last].r,k,op); return rt; } il int query(int l,int r,int s1,int s2,int k){ if(l==r) return l; int x=t[t[s2].l].x-t[t[s1].l].x; rep(i,1,tot1) x-=t[t[q1[i]].l].x; rep(i,1,tot2) x+=t[t[q2[i]].l].x; int mid=(l+r)>>1; if(x>=k){ rep(i,1,tot1) q1[i]=t[q1[i]].l; rep(i,1,tot2) q2[i]=t[q2[i]].l; return query(l,mid,t[s1].l,t[s2].l,k); } else{ rep(i,1,tot1) q1[i]=t[q1[i]].r; rep(i,1,tot2) q2[i]=t[q2[i]].r; return query(mid+1,r,t[s1].r,t[s2].r,k-x); } } struct node{ int op,l,r,k; }q[maxn]; il void runrk(){ sort(b+1,b+tot+1); sz=unique(b+1,b+tot+1)-(b+1); rep(i,1,sz) rk[b[i]]=i; } int main(){ sc(T); while(T--){ SC(n,m); tot=0,cnt=0,rk.clear(); rep(i,1,n) sc(a[i]),b[++tot]=a[i]; char op; int l,r,k; rep(i,1,m){ op=getchar(); while(!(op=='Q' || op=='C')) op=getchar(); if(op=='Q'){ SC(l,r),sc(k); q[i]=node{1,l,r,k}; } else{ SC(l,r); b[++tot]=r; q[i]=node{0,l,r,0}; } } runrk(); root[0]=root[1]=0; rep(i,1,n) root1[i]=root[1]; rep(i,1,n) root[i]=update(1,sz,root[i-1],rk[a[i]],1); rep(i,1,m){ if(q[i].op){ //query int x=q[i].l-1,y=q[i].r,k=q[i].k; tot1=0,tot2=0; while(x){ q1[++tot1]=root1[x]; x-=x&-x; } while(y){ q2[++tot2]=root1[y]; y-=y&-y; } int id=query(1,sz,root[q[i].l-1],root[q[i].r],k); printf("%d\n",b[id]); } else{ // modify int x=q[i].l,now=rk[q[i].r],pre=rk[a[x]]; a[x]=q[i].r; while(x<=n){ root1[x]=update(1,sz,root1[x],pre,-1); root1[x]=update(1,sz,root1[x],now,1); x+=x&-x; } } } } return 0; }

 


最新回复(0)