他的故事要从今天早上说起。
今天,集训。
他到普及组那边平均比他小两个年级的打比赛。
做完前两道后。他看到了这道题。
T3不过如此,经典的单调队列。
他写完了代码。发现过了样例时,他几乎想直接跳到下一题去。
可惜,大样例阻碍了他前进的步伐,他小心看了一遍代码,调小了精度。
#define double long double
果然,输出朝着答案靠近了。
不能再小了,但是还是不对。
他的心中掠过惊讶,但还是熟练地写出了一个分数结构体。
仍然不对。直到比赛结束,他都没有发现自己的错误。
出榜了,果不其然,他的分数排在前列。只是这道题,他33分的分数还没有旁边一个56分的暴力高。
心灰意冷的他打开了洛谷,找到这道题,发现这道题是个紫后不禁窃喜(最多评绿),他企图在时间上显现出正解的优越性,捍卫单调队列的最后尊严。
他提交了两份代码。
那号称是n2的诡术暴力拿了90分,一个点WA。虽然他的程序跑的飞快,但是只多快好省地拿到70分。
他被打败了,不得不向大家求助。
于是便有了下面两份代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
struct frac{
int x,y;
void yf(){
if(x==0||y==0) return;
int p=__gcd(x,y);
x/=p;y/=p;
}
frac(int a,int b){x=a;y=b;yf();}
frac(){x=0;y=1;}
bool operator<(const frac &b)const{
return x*b.y<y*b.x;
}
};
struct node{
int id,x,y;
frac t;
bool operator<(const node &b)const{
if(x==b.x) return y>b.y;
return x>b.x;
}
};
node a[1000005];
deque<node> v;
signed main(){
ios::sync_with_stdio(0);
cin>>n;
for(int i=0;i<n;i++){cin>>a[i].x;a[i].id=i;}
for(int i=0;i<n;i++){cin>>a[i].y;}
// cout<<a[272].x<<' '<<a[273].y<<endl;
sort(a,a+n);
a[0].t=frac(0,1);
v.push_back(a[0]);
// cout<<v.front().x<<endl;
for(int i=1;i<n;i++){
if(a[i].x==a[i].y) continue;
if(a[i].y<v.back().y) continue;
while(!v.empty()&&frac(v.back().x-a[i].x,a[i].y-v.back().y)<v.back().t){
v.pop_back();
// cout<<fixed<<v.back().t-(double)(v.back().x-a[i].x)/(a[i].y-v.back().y)<<endl;
}
v.push_back((node){a[i].id,a[i].x,a[i].y,frac(v.back().x-a[i].x,a[i].y-v.back().y)});
}
cout<<v.size()<<endl;
vector<int> ans;
while(!v.empty()){
ans.push_back(v.front().id+1);
v.pop_front();
}
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++) cout<<ans[i]<<' ';
return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct car{
int num;
int p;
double v;
}c[500010];
int n,b[500010],cnt;
bool cmp(const car &A,const car &B){
return A.p>B.p;
}
int main(){
// ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i].p;
c[i].num=i;
}
for(int i=1;i<=n;i++){
cin>>c[i].v;
}
sort(c+1,c+n+1,cmp);
for(int i=1;i<=n;i++){
if(c[i].p==c[1].p){
b[c[i].num]=1;
cnt++;
continue;
}
double t=0;
int x=1;
for(int j=1;j<i;j++){
double cha=c[i].v-c[j].v;
if(cha==0) continue;
if(cha<0){
x=0;
break;
}
double zhui=(c[j].p-c[i].p)/cha;
t=max(t,zhui);
}
if(x==0) continue;
for(int j=i+1;j<=n;j++){
if(t*c[i].v+c[i].p<t*c[j].v+c[j].p){
x=0;
break;
}
}
if(x==0) continue;
cnt++;
b[c[i].num]=1;
}
cout<<cnt<<endl;
for(int i=1;i<=n;i++){
if(b[i]) cout<<i<<" ";
}
}
求调!!!!!!!!