ABCD 略
E
注意到每个操作最多执行一次,ifa[i]!=b[i],要么a[i]^a[i+1]要么a[i]^b[i+1]
G
设消除1~i的数的操作次数为f[i],可以推出f[i]=2*f[i-1]+1,那么消除1~i的数的分数乘的数为g[i],g[i]=g[i-1]*g[i-1]*i s虽然很大,但是k只有1e9,先预处理fg,并且得到最大可以消除它和它衍生得到的数m。把所有数放到set,从小到大判断每个数及它的衍生数是否可以完全消去,可以则直接消去计算价值,否则拆乘成小于m的若干个数。思考会不会超时,答案是不会,像这种无法完全删去的情况最多出现m次,每次最多循环m
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N=2e5+10,mod=1e9+7;
int T,n,m,k,a[N],f[N],g[N],ans;
void init()
{
ans=1;
}
void solve()
{
cin>>n>>k;
init();
set<int> s;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s.insert(a[i]);
}
while(s.size()&&k)
{
int x=*s.begin();
s.erase(s.begin());
if(x<=m&&k>=f[x-1]+1)
{
ans=(ans*g[x-1]%mod*x)%mod;
k-=f[x-1]+1;
}
else
{
ans=(ans*x)%mod;
for(int i=1;i<min(m+1,x);i++)
s.insert(i);
k--;
}
}
cout<<ans<<endl;
}
signed main()
{
f[0]=0;g[0]=1;
for(m=1;;m++)
{
f[m]=f[m-1]*2+1;
g[m]=(g[m-1]*g[m-1]%mod*m)%mod;
if(f[m]>1e9) break;
}
ios::sync_with_stdio(0);
cin.tie(0);cout.tie();
cin>>T;
while(T--) solve();
}