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;
}
posted @ 2025-02-10 16:08  sad_lin  阅读(8)  评论(0)    收藏  举报