A.
最优直接用第一个人的力量值即可,比他小的数都不用思考,力量值比他大的如果耐力值也比他大于等于那就一定-1,否则输出第一个人的力量值即可
#include
using namespace std;
const int N = 2e5+10,mod=1e9+7;
#define int long long
typedef long long LL;
typedef pair PII;
int n,m;
PII a[N];
void solve(){
cin>>n;
map mp;
for(int i=1;i<=n;i++){
cin>>a[i].first>>a[i].second;
mp[{a[i].first,a[i].second}]++;
}
int c=a[1].first,d=a[1].second;
if(mp[{a[1].first,a[1].second}]>1){
cout<<"-1\n";
return ;
}
sort(a+1,a+1+n,[&](const auto&p,const auto&q){
return p.first=c) mx=max(mx,a[i].second);
}
if(mx>=d){
cout<<-1<<"\n";
return ;
}
cout<>t;
while(t--) solve();
}
B.
#include
using namespace std;
const int N = 3e5+10,mod=1e9+7;
#define int long long
typedef long long LL;
typedef pair PII;
int n,m;
int a[N],b[N];
void solve(){
cin>>n;
//4 6 3
//7 6 6
//4 3 3
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
int mn=*min_element(a+1,a+1+n);
int mn1=*min_element(b+1,b+1+n);
int res1=0,res2=0;
for(int i=1;i<=n;i++) res1+=(mn+b[i]);
for(int i=1;i<=n;i++)
res2+=(mn1+a[i]);
cout<>t;
while(t--) solve();
}
C.
理性分析:要么开头是0,要么开头1开始,所以可以枚举是1开头还是0开头
然后发现其实没必要,直接以字符串第一个字符开头就行,
我们先把每段连续的缩点
每个点里面只选一个数出来,其他点都要删
所以最小次数就是每个点的总和-点的总数
方案数就是要删除的个数的阶乘 * 每个点选择哪一个点出来当合法的0/1
#include
using namespace std;
const int N = 3e5+10,mod=998244353;
#define int long long
typedef long long LL;
typedef pair PII;
int n,m;
string s;
int fact[N];
void init(){
fact[0]=1;
for(int i=1;i a;
// a.push_back({(s[1]-'0'),0});
// for(int i=1;i<=n;i++)
// {
// int x=s[i]-'0';
// if(a.back().first==x) a.back().second++;
// else a.push_back({x,1});
// }
// PII get2(){
// int cnt=0,now=1;
// int res=0;
// vector a;
// a.push_back({(s[1]-'0'),0});
// for(int i=1;i<=n;i++)
// {
// int x=s[i]-'0';
// if(a.back().first==x) a.back().second++;
// else a.push_back({x,1});
// }
// ///000000
// for(auto [x,v]:a)
// {
// cnt+=v;
// if(x==now)
// {
// now^=1;
// res+=v-1;
// }
// else
// {
// res+=v;
// }
// }
// return {res,fact[cnt]};
// }
void solve(){
cin>>s;
n=s.size();
s="?"+s;
vector a;
a.push_back({(s[1]-'0'),0});
for(int i=1;i<=n;i++)
{
int x=(s[i]-'0');
if(a.back().first==x) a.back().second++;
else a.push_back({x,1});
}
int cnt=1,res=0;
for(auto [x,v]:a)
{
res+=v-1;
cnt=cnt*v%mod;
}
cout<>t;
while(t--) solve();
}
D:异或和考虑每个二进制进行思考
先进行前缀异或和,变成选两个数(s【r】^s[l-1])*(r-l+1)
如果第i下标的某个二进制当前位是1,那么我只要前面的数二进制当前位是0的数,否则答案是0不用考虑
考虑r-l+1
统计前面有多少个数异或和为0的个数,和异或和为0下标总和
然后(r-l+1)=个数*r-下标总和即可,(因为是s[l-1],所以那个+1已经考虑进去了)
#include
using namespace std;
const int N =3e5+10,mod= 998244353;
#define int long long
typedef long long LL;
typedef pair PII;
int n,m;
int a[N];
int s[N];
int cnt[2][35];
int d[2][35];
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int res=0;
//1 2 3 3
for(int i=1;i<=n;i++)
s[i]=a[i]^s[i-1];
for(int i=0;i<=n;i++)
{
for(int j=0;j<=30;j++)
{
int now=0;
if(s[i]>>j&1) now=0,d[1][j]=(d[1][j]+i)%mod;
else now=1,d[0][j]=(d[0][j]+i)%mod;
res+=(1<>t;
while(t--) solve();
}