枚举右端点 同时把已经扫过的左端点加入set 然后利用set二分找加和取余后的最大值
#include <bits/stdc++.h>
using namespace std;
#define ll long long
set <ll> st;
ll mat[4][100010],sum[4][100010];
ll mod;
int n;
int main()
{
ll val,ans;
int i,j;
while(scanf("%d%lld",&n,&mod)!=EOF)
{
for(i=1;i<=3;i++)
{
for(j=1;j<=n;j++)
{
scanf("%lld",&mat[i][j]);
mat[i][j]%=mod;
sum[i][j]=(sum[i][j-1]+mat[i][j])%mod;
}
}
st.clear();
ans=0;
for(i=1;i<=n;i++)
{
val=(sum[1][i]-sum[2][i-1]+mod)%mod;
st.insert(val);
val=(sum[2][i]-sum[3][i-1]+sum[3][n]+mod)%mod;
set <ll>::iterator it=st.lower_bound(mod-val);
if(it!=st.begin())
{
it--;
ans=max(ans,(val+*it)%mod);
}
}
printf("%lld\n",ans);
}
return 0;
}