4 条题解
-
1
一道不是特别难的题,但是场上不会做
首先注意到数据范围不是经典数字1e5,所以考虑 做法
分做法
提交下面代码即可:
#include<iostream> using namespace std; int main(){ 这是0分做法 return 0; }分做法
按照题意模拟
分做法
对于每一个 ,考虑他向右看能看到多少人,注意到对于一个 他能看到的 的斜率是单调递增的,直接暴力修改,模拟即可
#include<iostream> #include<cstdio> using namespace std; bool Test_MLE_start; constexpr int N=2005; int _=1,n,q,a[N]; inline int reads(){ char c=getchar(); int x=0,f=1; while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=(x<<3)+(x<<1)+(c^'0');c=getchar();} return x*f; } inline void files(){ freopen("std.in","r",stdin); freopen("std.out","w",stdout); } inline void clr(){ // Don't forget! } inline double calc(int a,int b,int c,int d){return (d-b)*1.0/(c-a)*1.0;} bool Test_MLE_end; signed main(){ // printf("%lf Mb\n",(&Test_MLE_end-&Test_MLE_start-1)/1024.0/1024.0); // files(); // _=reads(); while(_--){ clr();n=reads(); for(int i=1;i<=n;i++) a[i]=reads(); q=reads(); while(q--){ int x,y,ans=0; x=reads(),y=reads();a[x]+=y; for(int i=n;i>=1;i--){ double maxn=-2e9; for(int j=i+1;j<=n;j++){ double dududu=calc(i,a[i],j,a[j]); if(dududu>=maxn){ maxn=dududu; ans++; } } }printf("%d\n",ans); } } return 0; }分做法
我们考虑记录出来每一个 能看到谁,然后将一个 的高度增加可以将某些东西删除即可
我们使用set维护出来对于一个 能看到的所有的人的编号
我们每修改一个 ,首先查看 能不能被看到,如果不能被看到直接
break,如果能看到,将所有编号比 大且斜率比我的后面的人全部删掉直接暴力删除即可,因为对于每一个 ,只会加进set中 次,而每一个只会删除 次,所以时间复杂度是 的
#include<algorithm> #include<iostream> #include<cstdio> #include<set> #define N 2005 using namespace std; bool Test_MLE_start; int _=1,n,q,a[N]; multiset<int> st[N]; inline int reads(){ char c=getchar(); int x=0,f=1; while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=(x<<3)+(x<<1)+(c^'0');c=getchar();} return x*f; } inline void files(){ freopen("std.in","r",stdin); freopen("std.out","w",stdout); } inline void clr(){ // Don't forget! } inline double calc(int a,int b,int c,int d){return (d-b)*1.0/(c-a)*1.0;} bool Test_MLE_end; signed main(){ // printf("%lf Mb\n",(&Test_MLE_end-&Test_MLE_start-1)/1024.0/1024.0); // files(); // _=reads(); while(_--){ clr();n=reads(); for(int i=1;i<=n;i++) a[i]=reads(); for(int i=n;i>=1;i--){ double maxn=-2e9;st[i].insert(0),st[i].insert(n+1); for(int j=i+1;j<=n;j++){ double p=calc(i,a[i],j,a[j]); if(p>=maxn) maxn=p,st[i].insert(j); } }q=reads(); while(q--){ int x,y,ans=0;x=reads(),y=reads(); a[x]+=y; for(int i=1;i<x;i++){ auto pit=st[i].lower_bound(x);pit--; int p=(*pit); if(p&&calc(i,a[i],p,a[p])>calc(i,a[i],x,a[x])) continue; auto it=st[i].find(x); if(it==st[i].end()) st[i].insert(x); p=*st[i].upper_bound(x); while(p<=n){ if(calc(i,a[i],x,a[x])<=calc(i,a[i],p,a[p])) break; st[i].erase(p); p=*st[i].upper_bound(p); } }st[x].clear(),st[x].insert(0),st[x].insert(n+1); double maxn=-2e9; for(int j=x+1;j<=n;j++){ double p=calc(x,a[x],j,a[j]); if(p>=maxn) maxn=p,st[x].insert(j); }for(int i=1;i<=n;i++) ans+=st[i].size()-2; printf("%d\n",ans); } } return 0; }
信息
- ID
- 524
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 16
- 已通过
- 6
- 上传者