4 条题解

  • 1
    @ 2025-11-5 13:57:37

    一道不是特别难的题,但是场上不会做

    首先注意到数据范围不是经典数字1e5,所以考虑 O(n2)O(n^2) 做法

    00 分做法

    提交下面代码即可:

    #include<iostream>
    using namespace std;
    int main(){
        这是0分做法 
        return 0;
    }
    

    2020 分做法

    按照题意模拟

    5050 分做法

    对于每一个 ii,考虑他向右看能看到多少人,注意到对于一个 ii 他能看到的 jj 的斜率是单调递增的,直接暴力修改,模拟即可

    #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;
    }
    
    

    100100 分做法

    我们考虑记录出来每一个 ii 能看到谁,然后将一个 xx 的高度增加可以将某些东西删除即可

    我们使用set维护出来对于一个 ii 能看到的所有的人的编号

    我们每修改一个 axa_x,首先查看 axa_x 能不能被看到,如果不能被看到直接break,如果能看到,将所有编号比 xx 大且斜率比我的后面的人全部删掉

    直接暴力删除即可,因为对于每一个 axa_x,只会加进set中 n2n^2 次,而每一个只会删除 11 次,所以时间复杂度是 O(n2)O(n^2)

    #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
    上传者