2020CCPC 秦皇岛 E题

这个题可以尺取也可以权值线段树,我选择了权值线段树动态开点

我是sb

把数组按照a排序

1.如果没有人选a,那么分数线就按照b的最大值算

2.如果选了ai,那比ai小的aj都要选(贪心)

3.数字很大记得动态开点

没事了

非常可惜,其实我已经想到一半以上了,可惜看错了题。。。。秦皇岛两个铜题都很简单,非常可惜,如果多给我门一个小时说不定。。。。

 #include<iostream>

#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 6e7+111;
struct Node{
	int x,y;
}que[maxn];

int cnt = 0;

struct node{
	int l,r,ans;
}tree[maxn];


int update(int& node,int be,int en,int i,int val){
	if(node == 0) node = ++cnt;
	int mid = be + en >> 1;
	if(be == en){
		tree[node].ans += val;
		return 0;
	}
	if(i <= mid) update(tree[node].l,be,mid,i,val);
	else update(tree[node].r,mid+1,en,i,val);
	
	int l = tree[node].l;
	int r = tree[node].r;
	
	tree[node].ans = tree[l].ans + tree[r].ans;
	return 0;
}

int ask(int node,int be,int en,int LL,int RR){
	if(node == 0) return 0;
	
	int mid = be + en >> 1;
	if(LL <= be && en <= RR){
		return tree[node].ans;
	}
	int val1 = 0,val2 = 0;
	if(LL <= mid) val1 = ask(tree[node].l,be,mid,LL,RR);
	if(RR > mid) val2 = ask(tree[node].r,mid+1,en,LL,RR);
    
	return val1 + val2;
}
int vis[500050];

bool bml(Node a,Node b){
	return a.x > b.x;
}


int main(){
	int t;
	int aa = 0;
	scanf("%d",&t);
	
	while(t--){
		int n;
		double p;
		scanf("%d%lf",&n,&p);
		p/=100;
		
		int len = 0;
		cnt = 2;
		int root = 1;
		
		
		int nn = 2e9;
		
		for(int i=0;i<n;i++){
			scanf("%d %d",&que[i].x,&que[i].y);			
		}
		sort(que,que+n,bml);
		int mx = -1;
		for(int i=0;i<n;i++){
			update(root,1,nn,que[i].x,1);
		}
		int ans = 0;
		
		
		for(int i=0;i<n;i++){
			int cns;
			if(que[i].x > mx){
				int r = ceil(1.0*que[i].x*p);
				cns = ask(root,1,nn,r,que[i].x);
			}
			else{
				int r = ceil(1.0*mx*p);
				cns = ask(root,1,nn,r,mx);
			}
			ans = max(ans,cns);
			
			update(root,1,nn,que[i].y,1);	
			update(root,1,nn,que[i].x,-1);
			mx = max(mx,que[i].y);
		}
		int r = ceil(1.0*mx*p);
		int	cns = ask(root,1,nn,r,mx);
		ans = max(ans,cns);
		
		
		for(int i=0;i<=cnt;i++){
			tree[i].ans = tree[i].l = tree[i].r = 0;
		}
		cnt = 0;
		printf("Case #%d: %d
",++aa,ans);
		
	}
	return 0;
}

提供一种类似尺取的写法,记得所有人都在的时候才能算入答案

这个更骚

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 6e7+111;
struct Node{
	int val;
	int id;
}que[maxn];
bool bml(Node a,Node b){
	return a.val < b.val;
}
int cnt = 0;
struct node{
	int l,r,ans;
}tree[maxn];
int update(int& node,int be,int en,int i,int val){
	if(node == 0) node = ++cnt;
	int mid = be + en >> 1;
	if(be == en){
		tree[node].ans += val;
		return 0;
	}
	if(i <= mid) update(tree[node].l,be,mid,i,val);
	else update(tree[node].r,mid+1,en,i,val);
	int l = tree[node].l;
	int r = tree[node].r;
	
	tree[node].ans = tree[l].ans + tree[r].ans;
	return 0;
}
int ask(int node,int be,int en,int LL,int RR){
	if(node == 0) return 0;
	int mid = be + en >> 1;
	if(LL <= be && en <= RR){
		return tree[node].ans;
	}
	int val1 = 0,val2 = 0;
	if(LL <= mid) val1 = ask(tree[node].l,be,mid,LL,RR);
	if(RR > mid) val2 = ask(tree[node].r,mid+1,en,LL,RR);
	return val1 + val2;
}
int vis[200050];

int main(){

	int t;
	int aa = 0;
	scanf("%d",&t);
	while(t--){
		int n;
		double p;
		scanf("%d %lf",&n,&p);
		p/=100;
		int len = 0;
		cnt = 2;
		int root = 1;
		
		for(int i=1;i<=n;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			vis[i] = 0;
			que[len].val = a;
			que[len].id = i;
			len++;
			que[len].val = b;
			que[len].id = i;
			len++;
		}
		int nn = 1e9 + 11111;
		
		sort(que,que+len,bml);
		
		int ans = 0;
		int cnn = 0;
		
		for(int i=0;i<len;i++){
			if(vis[que[i].id] != 0){
				update(root,1,nn,vis[que[i].id],-1);
			}
			update(root,1,nn,que[i].val,1);
			if(vis[que[i].id] == 0)	cnn++;
			
			
			vis[que[i].id] = que[i].val;
			double c = que[i].val;
			int r = c * p + 0.99999;
			
			int cns = ask(root,1,nn,r,que[i].val);
			if(cnn == n) ans = max(ans,cns);
		}
		
		
		for(int i =0 ;i<=cnt;i++){
			tree[i].l = tree[i].r = tree[i].ans = 0;
		}
		cnt = 2;
		printf("Case #%d: %d
",++aa,ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/lesning/p/13929037.html