2 条题解
-
6
标题
黑洞题解
思路
对于每一个维度,会有正反两个方向。总共有 种方法,确定他的对角线长度取决于所有维度的最小值。所以找到最小值就有一半的方法的答案贡献是最小值,也就是 。再找次小值,以此类推。 特别的,当取到两个同维度的,则不需要取一半。
解题方法
使用 数组记录 对 取余的结果。再存储每一个方向的长度,记录维度,排序。
复杂度
时间复杂度:
空间复杂度:
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
标题
大标题大标题大标题大标题
思路
考虑暴力,对于每个方向,先求出它向正、负延伸的范围,再 计算向正还是负延伸。
优化,发现每一次能延伸多少只看其中最小的,而且顺序不影响答案,所以可以按向正、负延伸的范围的最小值排序,一旦后面的最小值都比当前最小值还大,再搜索没有意义,直接加上后面总共的贡献返回即可。
做完后看了一眼数据范围,能过,奇迹啊时间复杂度:
十年OI一场空,不开long long见祖宗
#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
- 上传者