2 条题解

  • 6
    @ 2024-10-20 14:55:49

    标题

    黑洞题解

    思路

    对于每一个维度,会有正反两个方向。总共有 2n2^n 种方法,确定他的对角线长度取决于所有维度的最小值。所以找到最小值就有一半的方法的答案贡献是最小值,也就是 2n12^{n-1} 。再找次小值,以此类推。 特别的,当取到两个同维度的,则不需要取一半。

    解题方法

    使用 xpxp 数组记录 2n2^nmodmod 取余的结果。再存储每一个方向的长度,记录维度,排序。

    复杂度

    时间复杂度:

    O(nlogn)O(nlogn)

    空间复杂度:

    O(n)O(n)

    Code

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    bool b[1000030];
    const int mod=1e9+7;
    int n,m[1000030],a[1000030],xp[1000030];
    struct node{
    	int sum,num;
    };
    bool cmp(node x,node y){
    	return x.sum<y.sum;
    }
    vector<node> v;
    signed main(){
    //	freopen("hole7.in","r",stdin);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>m[i];
    	}
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    		v.push_back({a[i]-1,i});
    		v.push_back({m[i]-a[i],i});
    	}
    	sort(v.begin(),v.end(),cmp);
    	xp[0]=1;
    	for(int i=1;i<=n;i++){
    		xp[i]=xp[i-1]*2;
    		xp[i]%=mod;
    	}
    	int idx=n,sum=0;
    	for(auto i:v){
    		if(b[i.num]){
    			sum+=i.sum*xp[idx];
    			sum%=mod;
    			break;
    		}
    		else{
    			idx--;
    			b[i.num]=1;
    			sum+=i.sum*xp[idx];
    			sum%=mod;
    		}
    	}
    	cout<<(sum+1)%mod;
    }
    
    
  • 0
    @ 2024-10-25 17:47:25

    标题

    大标题大标题大标题大标题

    思路

    考虑暴力,对于每个方向,先求出它向正、负延伸的范围,再 O(2n)O(2^n) 计算向正还是负延伸。

    优化,发现每一次能延伸多少只看其中最小的,而且顺序不影响答案,所以可以按向正、负延伸的范围的最小值排序,一旦后面的最小值都比当前最小值还大,再搜索没有意义,直接加上后面总共的贡献返回即可。
    做完后看了一眼数据范围,2e52e5能过,奇迹啊

    时间复杂度:

    O(2n)O(2^n)

    十年OI一场空,不开long long见祖宗

    ACAC CodeCode

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e6+7;
    const int Mod=1e9+7;
    int n,m[N],mi[N]={1};
    struct node{
    	int x,y;
    }a[N];
    int h[N];
    int ans=1;
    void dfs(int x,int minn){
    	if(x==n+1){
    		ans+=minn;
    		ans%=Mod;
    		return;
    	}
    	if(minn<=h[x]){
    		ans+=minn*mi[n-x+1]%Mod;
    		ans%=Mod;
    		return;
    	}
    	dfs(x+1,min(minn,a[x].x));
    	dfs(x+1,min(minn,a[x].y));
    }
    bool cmp(node A,node B){
    	return min(A.x,A.y)<min(B.x,B.y);
    }
    signed main(){
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		mi[i]=mi[i-1]*2%Mod;
    		cin>>m[i];
    	}
    	for(int i=1;i<=n;i++){
    		int x;
    		cin>>x;
    		a[i].x=m[i]-x;
    		a[i].y=x-1;
    	}
    	sort(a+1,a+1+n,cmp);
    	h[n+1]=1e18;
    	for(int i=n;i>=1;i--){
    		h[i]=min(h[i+1],min(a[i].x,a[i].y));
    	}
    	dfs(1,1e18);
    	cout<<ans;
    }
    

    暴力卍岁!!!(佛教,申和注意一下)

    • 1

    信息

    ID
    82
    时间
    3000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    385
    已通过
    74
    上传者