题解:P11971 「ALFR Round 7」T4 xor xor
大家不要像我一样不打单独的一场 div2。
对于这道题,可以发现他的异或操作差不多是个诈骗,因为当你一个区间里面
接着发现题目中保证
继续想可以发现,把个数大于
现在相当于答案为个数少于
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 1000010
const int mod=1e9+7;
int n,q,a[N],h[N],bas[N],s[N][2];
int gt0(int l,int r){
return s[r][0]-s[l-1][0];
}
int gt1(int l,int r){
return s[r][1]-s[l-1][1];
}
int gth(int l,int r){
return (h[r]-h[l-1]*bas[r-l+1]%mod+mod)%mod;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
bas[0]=1;
for(int i=1;i<=1000000;i++){
bas[i]=bas[i-1]*2%mod;
}
cin>>n>>q;
for(int i=1;i<=n;i++){
char c;
cin>>c;
if(c=='1'){
a[i]=1;
}
s[i][0]=s[i-1][0];
s[i][1]=s[i-1][1];
s[i][a[i]]++;
}
for(int i=1;i<=n;i++){
h[i]=(h[i-1]*2%mod+a[i])%mod;
}
while(q--){
int l,r,k;
bool fl=0;
cin>>l>>r>>k;
if(gt0(l,r)>=k&>1(l,r)>=k){
cout<<(bas[k]-1+mod)%mod<<'\n';
continue;
}
if(gt0(l,r)>=k){
fl=1;
}
int le=l,ri=r,pos;
while(le<=ri){
int mid=(le+ri)>>1;
int tmp=fl?gt1(l,mid):gt0(l,mid);
if(tmp+r-mid<k){
ri=mid-1;
}
else{
pos=mid;
le=mid+1;
}
}
cout<<((bas[fl?gt1(l,pos):gt0(l,pos)]-1+mod)*bas[k-(fl?gt1(l,pos):gt0(l,pos))]%mod+(fl?((pos==r)?0:gth(pos+1,r)):(bas[k-(fl?gt1(l,pos):gt0(l,pos))]-((pos==r)?0:gth(pos+1,r))-1+mod)))%mod<<'\n';
}
return 0;
}