题解:P11910 [THSPC 2023] I. 对战机器马
题目传送门
其实是很简单的题 ,但赛时脑抽了没写出来,赛后 40min 才过。
题目分析
考虑在什么情况下
我们显然只需考虑
分两种情况讨论:
-
a_i\ge b_i 此时比较显然,需满足
a_i<b_i+x<P ,解得a_i-b_i+1\le x\le P-b_i-1 。 -
a_i<b_i 此时有两种情况:
当
b_i+x<P 时,只需满足0\le x\le P-b_i-1 。当
b_i+x\le P 时,此时(b_i+x)\bmod P = b_i+x-P ,需满足b_i+x-P > a_i ,即a_i-b_i+P+1\le x\le P-1 。
显然可以先离散化。因为在一个小段中无论
然后考虑枚举
在枚举
AC Code
// by wangyizhi(571247)
#include<bits/stdc++.h>
//#include<bits/extc++.h>
using namespace std;
using ll=long long;
using ld=long double;
//#define int ll
using pii=pair<int,int>;
//bool Mst;
const int N=1e6+5;
int a[N],b[N],lsh[N];
int t[N<<2],tag[N<<2];
vector<int> in[N],out[N];
inline int ls(int id){return id<<1;}
inline int rs(int id){return id<<1|1;}
inline void push_up(int id){t[id]=max(t[ls(id)],t[rs(id)]);}
inline void __upd(int id,int x){t[id]+=x,tag[id]+=x;}
inline void push_down(int id){__upd(ls(id),tag[id]),__upd(rs(id),tag[id]),tag[id]=0;}
void update(int l,int r,int v,int id,int nl,int nr)
{
if(l<=nl&&r>=nr) return __upd(id,v),void();
push_down(id);
int m=(nl+nr)>>1;
if(l<=m) update(l,r,v,ls(id),nl,m);
if(r>m) update(l,r,v,rs(id),m+1,nr);
push_up(id);
}
int qry(){return t[1];}
#define root 1,1,c
//bool Med;
signed main()
{
// cerr<<"Memory Size: "<<abs((&Med)-(&Mst))/1024.0/1024<<" MB\n";
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n,p,c=0,res=0,ans=0;
cin>>n>>p;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++)
{
if(a[i]>=b[i]) lsh[++c]=a[i]-b[i]+1,lsh[++c]=p-b[i]-1;
else lsh[++c]=0,lsh[++c]=p-b[i]-1,lsh[++c]=a[i]-b[i]+1+p,lsh[++c]=p-1;
}
sort(lsh+1,lsh+c+1),c=unique(lsh+1,lsh+c+1)-lsh-1;
auto g=[&](int x){return lower_bound(lsh+1,lsh+c+1,x)-lsh;};
auto upd=[&](int i,int v)
{
if(a[i]>=b[i])
{
if(a[i]-b[i]+1<=p-b[i]-1) update(g(a[i]-b[i]+1),g(p-b[i]-1),v,root);
}
else
{
update(g(0),g(p-b[i]-1),v,root);
if(a[i]-b[i]+1+p<=p-1) update(g(a[i]-b[i]+1+p),g(p-1),v,root);
}
};
for(int i=1;i<=n;i++)
{
if(a[i]>=b[i])
{
if(a[i]-b[i]+1<=p-b[i]-1) in[g(a[i]-b[i]+1)].push_back(i),out[g(p-b[i]-1)].push_back(i);
}
else
{
in[g(0)].push_back(i),out[g(p-b[i]-1)].push_back(i);
if(a[i]-b[i]+1+p<=p-1) in[g(a[i]-b[i]+1+p)].push_back(i),out[g(p-1)].push_back(i);
}
}
for(int i=1;i<=n;i++) upd(i,1);
for(int k=1;k<=c;k++)
{
for(int i:in[k]) upd(i,-1),res++;
ans=max(ans,res+qry());
for(int i:out[k]) upd(i,1),res--;
}
cout<<ans<<"\n";
return 0;
}