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