【题解】「BZOJ4504」K个串

考虑二分答案 233

如果子树 max ⁡ \max max 都不能作为答案的话,就直接返回。

每找到一个叶节点就统计一次次数。

空间复杂度 O ( n log n ) O(n\text{log}n) O(nlogn)

时间复杂度 O ( ( n + k log n ) log N ) O((n+k\text{log}n)\text{log}N) O((n+klogn)logN)

#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e5+5; inline int read() { int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=(x<<1)+(x<<3)+c-'0'; c=getchar(); } return x*f; } int n,K,rt[N],tot; map<int,int> c; struct node { ll lc,rc,tag,max; }t[N<<6]; void pushup(int o) { t[o].max=max(t[t[o].lc].max,t[t[o].rc].max)+t[o].tag; } int upd(int o,int l,int r,int ql,int qr,int x) { int oo=++tot; t[oo]=t[o]; int mid=(l+r)/2; if(ql<=l&&r<=qr) { t[oo].tag+=x; t[oo].max+=x; return oo; } if(ql<=mid) t[oo].lc=upd(t[oo].lc,l,mid,ql,qr,x); if(mid<qr) t[oo].rc=upd(t[oo].rc,mid+1,r,ql,qr,x); pushup(oo); return oo; } void qry(int o,int l,int r,int ql,int qr,ll sol,int &ans) { if(!ans) return; if(t[o].max<sol) { return; } sol-=t[o].tag; if(l==r) { ans--; return; } int mid=(l+r)/2; if(ql<=mid) qry(t[o].lc,l,mid,ql,qr,sol,ans); if(mid<qr) qry(t[o].rc,mid+1,r,ql,qr,sol,ans); } bool check(ll mid) { int rest=K; for(int i=n;i>=1;i--) { qry(rt[i],1,n,1,i,mid,rest); if(!rest) return 1; } return 0; } signed main() { // freopen("data.in","r",stdin); n=read(),K=read(); for(int i=1;i<=n;i++) { int x=read(); rt[i]=upd(rt[i-1],1,n,c[x]+1,i,x); c[x]=i; } ll l=-1e18,r=1e18,res=0; while(l<=r) { ll mid=(l+r)/2; if(check(mid)) { res=mid,l=mid+1; } else { r=mid-1; } } printf("%lld",res); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530186.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示