这个题可以尺取也可以权值线段树,我选择了权值线段树动态开点
我是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;
}