BZOJ 3110
http://www.lydsy.com/JudgeOnline/problem.php?id=3110
整体二分+区间修改树状数组维护
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include<cstdio> #define FOR(i,s,t) for(register int i=s;i<=t;++i) inline int max( int a, int b){ return a>b?a:b;} inline int min( int a, int b){ return a<b?a:b;} typedef long long ll; const int N=50011,inf=(1<<30); int n,m,minn,maxx; int ans[N]; ll tmp[N]; namespace BIT{ ll tr1[N],tr2[N]; inline void add(ll *a, int p,ll v){ for (;p<=n;a[p]+=v,p+=p&-p); } inline ll query(ll *a, int p){ ll ret=0; for (;p;ret+=a[p],p-=p&-p); return ret; } inline void _add( int l, int r,ll v){ add(tr1,l,v);add(tr1,r+1,-v); add(tr2,l,1ll*(l-1)*v);add(tr2,r+1,-1ll*r*v); } inline ll _query(ll l,ll r){ ll ans1=1ll*(l-1)*query(tr1,l-1)-1ll*query(tr2,l-1); ll ans2=1ll*r*query(tr1,r)-1ll*query(tr2,r); return ans2-ans1; } } using namespace BIT; namespace divide{ struct question{ int a,b,c,k,pos; }p[N],t[N]; inline void solve( int l, int r, int head, int tail){ if (head>tail) return ; if (l==r){ FOR(i,head,tail) if (p[i].k==2) ans[p[i].pos]=l; return ; } int mid=(l+r)>>1; FOR(i,head,tail){ if (p[i].k==1&&p[i].c>mid)_add(p[i].a,p[i].b,1ll); if (p[i].k==2)tmp[i]=_query(p[i].a,p[i].b); } int top=head,d; FOR(i,head,tail){ if (p[i].k==1&&p[i].c>mid)t[top++]=p[i],_add(p[i].a,p[i].b,-1ll); if (p[i].k==2) if (p[i].c<=tmp[i])t[top++]=p[i]; } d=top; FOR(i,head,tail){ if (p[i].k==1&&p[i].c<=mid)t[top++]=p[i]; if (p[i].k==2) if (p[i].c>tmp[i])p[i].c-=tmp[i],t[top++]=p[i]; } FOR(i,head,tail)p[i]=t[i]; solve(mid+1,r,head,d-1); solve(l,mid,d,tail); } } using namespace divide; int main(){ scanf( "%d%d" ,&n,&m); minn=inf,maxx=-inf; FOR(i,1,m){ scanf( "%d%d%d%d" ,&p[i].k,&p[i].a,&p[i].b,&p[i].c); if (p[i].k==2)p[i].pos=++ans[0]; if (p[i].k==1)minn=min(minn,p[i].c),maxx=max(maxx,p[i].c); } solve(minn,maxx,1,m); FOR(i,1,ans[0])printf( "%d\n" ,ans[i]); return 0; } |
补一份树套树
树状数组套主席树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #include<cstdio> #include<algorithm> #define lson l,mid #define rson (mid+1),r using namespace std; const int maxn=1e5,N=3000000; int n,m,tot; int root[maxn],ra[maxn],rb[maxn]; int a[maxn],b[maxn]; struct Query{ char type; int l,r,k; }q[maxn]; struct Chainman_Tree{ int ls,rs,sum; }tr[N]; namespace BIT_with_Chainman_Tree{ inline void insert( int &rt, int p, int v, int l=1, int r=b[0]){ tr[++tot]=tr[rt]; tr[rt=tot].sum+=v; if (l==r) return ; int mid=(l+r)>>1; p<=mid?insert(tr[rt].ls,p,v,lson):insert(tr[rt].rs,p,v,rson); } inline int ask( int k, int l=1, int r=b[0]){ if (l==r) return l; register int sum=0; for (register int i=1;i<=ra[0];++i)sum-=tr[tr[ra[i]].ls].sum; for (register int i=1;i<=rb[0];++i)sum+=tr[tr[rb[i]].ls].sum; int mid=(l+r)>>1; if (k<=sum){ for (register int i=1;i<=ra[0];++i)ra[i]=tr[ra[i]].ls; for (register int i=1;i<=rb[0];++i)rb[i]=tr[rb[i]].ls; return ask(k,lson); } for (register int i=1;i<=ra[0];++i)ra[i]=tr[ra[i]].rs; for (register int i=1;i<=rb[0];++i)rb[i]=tr[rb[i]].rs; return ask(k-sum,rson); } inline int query( int l, int r, int k){ ra[0]=rb[0]=0; for (register int i=l-1;i;i-=i&-i)ra[++ra[0]]=root[i]; for (register int i=r;i;i-=i&-i)rb[++rb[0]]=root[i]; return ask(k); } inline void modify( int pos, int val, int v){ for (;pos<=n;pos+=pos&-pos) insert(root[pos],val,v); } } using namespace BIT_with_Chainman_Tree; inline void disc_init(){ sort(b+1,b+b[0]+1); b[0]=unique(b+1,b+b[0]+1)-b-1; for (register int i=1;i<=n;++i){ a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b; modify(i,a[i],1); } } char s[6]; int main(){ scanf( "%d%d" ,&n,&m); for (register int i=1;i<=n;++i){ scanf( "%d" ,a+i); b[++b[0]]=a[i]; } for (register int i=1;i<=m;++i){ scanf( "%s" ,s); q[i].type=s[0]; if (q[i].type== 'C' ){ scanf( "%d%d" ,&q[i].l,&q[i].k); b[++b[0]]=q[i].k; } else scanf( "%d%d%d" ,&q[i].l,&q[i].r,&q[i].k); } disc_init(); for (register int i=1;i<=m;++i){ if (q[i].type== 'C' ){ q[i].k=lower_bound(b+1,b+b[0]+1,q[i].k)-b; modify(q[i].l,a[q[i].l],-1); a[q[i].l]=q[i].k; modify(q[i].l,a[q[i].l],1); } else printf( "%d\n" ,b[query(q[i].l,q[i].r,q[i].k)]); } return 0; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步