CF1788D
前言
这道题场切了,居然是蓝的。
思路
我们可以发现不能暴力,然后我们可以枚举一个左右端点然后我们来算它们都往中间走能产生的贡献,我们可以发现能起到贡献的就是不跟着 \(i\) 和 \(j\) 的方案数,那么我们可以给出一个区间 \(l\sim r\) 表示在这个区间内的都会跟着 \(i\) 和 \(j\) 走到中间,那么我们就可以发现若在这个区间之外的有 \(cnt\) 个那么就会有 \(2^{cnt}\) 个贡献,所以我们就可以用二分来算出这个区间然后用总的减一下即可。
代码
#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define rep1(i,x,y) for(int i=x;i>=y;i--)
#define il inline
#define in(x) scanf("%lld",&x)
#define w(x) while(x--)
int t;
int n;
const int mod=1e9+7,N=100010;
int a[N],res;
int qmi(int a,int b) {
int res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
signed main() {
in(n);
rep(i,1,n) in(a[i]);
rep(i,1,n) {
rep(j,i+1,n) {
int l=a[j]-a[i]+1;
int x=a[i]-l+1,y=a[j]+l-1;
int tx=lower_bound(a+1,a+1+n,x)-a-1;
int ty=lower_bound(a+1,a+1+n,y)-a-1;
res=(res+qmi(2,n-ty+tx))%mod;
}
}
cout<<res<<endl;
return false;
}

浙公网安备 33010602011771号