T-Shirts
T-Shirts
将人按钱数从小到大排序,想到对于每个物品可以对一个区间内的人进行影响,那我们建立平衡树,将人的作为其中的元素插入,将物品按品质价格排序,每次看作是一个操作进行区间修改。
不过不能修改后不做处理,如果打上减标记后权值减少可以会造成权值相交,我们再插回去的话就不满足平衡树的性质了。
考虑将 \([c,2c]\) 的节点暴力插入 \([1,c-1]\),对于 \([2c+1,n]\) 的节点打标记处理,为什么暴力是对的,因为满足 \([c,2c]\) 的节点减 \(c\) 对半,每个点最多操作 \(logc_i\) 次。
#include<bits/stdc++.h> #define ll long long #define int ll #define ls t[p].l #define rs t[p].r #define re register #define pb push_back #define pir pair<int,int> #define f(a,x,i) for(int i=a;i<=x;i++) #define fr(a,x,i) for(int i=a;i>=x;i--) using namespace std; const int N=4e5+10; const int M=3e5+10; const int mod=1e9+7; mt19937 rnd(251); int n,m; int cnt=0; int root=0; struct ss{ int c,q; }a[N]; int ans[N]; bool cmp(ss g,ss h){ if(g.q!=h.q){ return g.q>h.q; } return g.c<h.c; } struct Tree{ int rnd; int l,r; int val; int id; int cnt; int tag1,tag2; }t[N]; void pushdown(int p){ if(t[p].tag1){ int c=t[p].tag1; if(t[p].l) t[ls].tag1+=c,t[ls].val-=c; if(t[p].r) t[rs].tag1+=c,t[rs].val-=c; t[p].tag1=0; } if(t[p].tag2){ int c=t[p].tag2; if(t[p].l) t[ls].tag2+=c,t[ls].cnt+=c; if(t[p].r) t[rs].tag2+=c,t[rs].cnt+=c; t[p].tag2=0; } } void split(int p,int val,int &x,int &y){ if(!p){ x=y=0; return; } pushdown(p); if(t[p].val<=val){ x=p; split(t[p].r,val,t[p].r,y); } else{ y=p; split(t[p].l,val,x,t[p].l); } } int merge(int x,int y){ if(!x||!y){ return x+y; } pushdown(x); pushdown(y); if(t[x].rnd<t[y].rnd){ t[x].r=merge(t[x].r,y); return x; } else{ t[y].l=merge(x,t[y].l); return y; } } int add(int val,int id){ int p=++cnt; t[p].rnd=rnd(); t[p].id=id; t[p].val=val; return p; } void insert(int val,int id){ int x,y; split(root,val,x,y); int z=add(val,id); root=merge(merge(x,z),y); } void dfs(int x,int &y,int z){ if(!x) return; pushdown(x); dfs(t[x].l,y,z); dfs(t[x].r,y,z); t[x].l=t[x].r=0; t[x].cnt++; t[x].val-=z; int k1,k2; split(y,t[x].val,k1,k2); y=merge(merge(k1,x),k2); } void dfs2(int p){ if(!p) return; pushdown(p); ans[t[p].id]=t[p].cnt; dfs2(ls);dfs2(rs); } signed main(){ // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); ios::sync_with_stdio(0); cin.tie(nullptr); cin>>n; for(int i=1;i<=n;i++){ cin>>a[i].c>>a[i].q; } sort(a+1,a+1+n,cmp); cin>>m; for(int i=1;i<=m;i++){ int x; cin>>x; insert(x,i); } for(int i=1;i<=n;i++){ int x,y,z; int c=a[i].c; split(root,c-1,x,y); split(y,2*c,y,z); if(z){ t[z].val-=c; t[z].tag1+=c; t[z].cnt++; t[z].tag2++; } dfs(y,x,c); root=merge(x,z); } dfs2(root); for(int i=1;i<=m;i++){ cout<<ans[i]<<" "; } return 0; }
有交合并,未优化不能过。
#include<bits/stdc++.h> #define ll long long #define int ll #define ls t[p].l #define rs t[p].r #define re register #define pb push_back #define pir pair<int,int> #define f(a,x,i) for(int i=a;i<=x;i++) #define fr(a,x,i) for(int i=a;i>=x;i--) using namespace std; const int N=2e5+10; const int M=3e5+10; const int mod=1e9+7; mt19937 rnd(251); int n,m; int cnt=0; int root=0; struct ss{ int c,q; }a[N]; int ans[N]; bool cmp(ss g,ss h){ if(g.q!=h.q){ return g.q>h.q; } return g.c<h.c; } struct Tree{ int rnd; int l,r; int val; int id; int cnt; int tag1,tag2; }t[N]; void pushdown(int p){ if(t[p].tag1){ int c=t[p].tag1; if(t[p].l) t[ls].tag1+=c,t[ls].val-=c; if(t[p].r) t[rs].tag1+=c,t[rs].val-=c; t[p].tag1=0; } if(t[p].tag2){ int c=t[p].tag2; if(t[p].l) t[ls].tag2+=c,t[ls].cnt+=c; if(t[p].r) t[rs].tag2+=c,t[rs].cnt+=c; t[p].tag2=0; } } void split(int p,int val,int &x,int &y){ if(!p){ x=y=0; return; } pushdown(p); if(t[p].val<=val){ x=p; split(t[p].r,val,t[p].r,y); } else{ y=p; split(t[p].l,val,x,t[p].l); } } int merge(int x,int y){ if(!x||!y){ return x|y; } if(t[x].rnd<t[y].rnd){ pushdown(x); t[x].r=merge(t[x].r,y); return x; } else{ pushdown(y); t[y].l=merge(x,t[y].l); return y; } } int merge2(int x,int y){ if(!x||!y){ return x|y; } int l,r; if(t[x].rnd<=t[y].rnd){ pushdown(x); split(y,t[x].val,l,r); t[x].l=merge2(t[x].l,l); t[x].r=merge2(t[x].r,r); return x; } else{ pushdown(y); split(x,t[y].val,l,r); t[y].l=merge2(t[y].l,l); t[y].r=merge2(t[y].r,r); return y; } } int add(int val,int id){ int p=++cnt; t[p].rnd=rnd(); t[p].id=id; t[p].val=val; return p; } void insert(int val,int id){ int x,y; split(root,val,x,y); int z=add(val,id); root=merge(merge(x,z),y); } void dfs2(int p){ if(!p) return; pushdown(p); ans[t[p].id]=t[p].cnt; dfs2(ls);dfs2(rs); } signed main(){ // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); ios::sync_with_stdio(0); cin.tie(nullptr); cin>>n; for(int i=1;i<=n;i++){ cin>>a[i].c>>a[i].q; } sort(a+1,a+1+n,cmp); cin>>m; for(int i=1;i<=m;i++){ int x; cin>>x; insert(x,i); } for(int i=1;i<=n;i++){ int x,y,z; int c=a[i].c; split(root,c-1,x,y); split(y,2*c-1,y,z); if(y){ t[y].cnt++; t[y].val-=c; t[y].tag1+=c; t[y].tag2++; } if(z){ t[z].cnt++; t[z].val-=c; t[z].tag1+=c; t[z].tag2++; } root=merge(merge2(x,y),z); } dfs2(root); for(int i=1;i<=m;i++){ cout<<ans[i]<<" "; } return 0; }
标签:
平衡树
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具