题意

数轴上有两个人,告诉你每个人的指令,即向左/右/不动维持多久,可以随意选择出发点,使得两人在整点位置的见面次数最多

题解

设时刻 i i i , a a a 的位置为 A [ i ] = A [ i 1 ] + R a [ i ] A[i]=A[i-1]+R_a[i] A[i]=A[i1]+Ra[i] , b b b 的位置为 B [ i ] = B [ i 1 ] + R b [ i ] B[i]=B[i-1]+R_b[i] B[i]=B[i1]+Rb[i]
相距 D [ i ] = A [ i ] B [ i ] D[i]=A[i]-B[i] D[i]=A[i]B[i]
显然,见面次数最多,就是 D [ i ] D[i] D[i] 中出现频率最高的数的个数
对于 D [ i ] D[i] D[i] ,最多有 2 N 2N 2N 个转折点,每个转折点有可能为五种
0 , 1 , 1 , 2 , 2 0,1,-1,2,-2 0,1,1,2,2
针对这5种情况,就知道相邻指令之间经过的距离的范围了,相当于对于距离进行区间覆盖,最后前缀和,找最大的数

注意要分奇偶
因为,对于 0 , 1 , 1 0,1,-1 0,1,1 距离都是连续覆盖的,但是,对于 2 , 2 2,-2 2,2 来说,是隔一个覆盖一个距离,而题目要求在整点位置见面才算数,所以,间隔的距离是不能统计的,比如相邻指令经过的距离为 3 , 5 , 7 , 9 3,5,7,9 3,5,7,9 显然不能对 [ 3 , 9 ] [3,9] [3,9]进行覆盖,因为 2 , 4 , 6 , 8 2,4,6,8 2,4,6,8 不能算是出现过
分奇偶,只需要对 1 , 1 1,-1 1,1 的情况,拆成两个进行覆盖即可

代码

#include<bits/stdc++.h>
#define N 400010
#define INF 0x3f3f3f3f
#define eps 1e-5
#define pi 3.141592653589793
#define mod 1000000007
#define P 1000000007
#define LL long long
#define pb push_back
#define fi first
#define se second
#define cl clear
#define si size
// #define lb lower_bound
#define ub upper_bound
#define bug(x) cerr<<#x<<" : "<<x<<endl
#define mem(x,y) memset(x,0,sizeof(int)*(y+3))
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;

int n,m;
struct node{
    LL x,y;
}A[N],B[N];
LL q[N],a[2][N],b[2][N],c[2][N],d[N],w[2][N];
int s[2],r[2];
void update(LL x,LL y,LL d,int k){
    int t=x&1;
    a[t][++s[t]]=x; b[t][s[t]]=y; 
    w[t][++r[t]]=x; w[t][++r[t]]=y;
    if (d==0) c[t][s[t]]=q[k+1]-q[k];
    else c[t][s[t]]=1;
}

int main()
{
    int T; sc(T);
    while(T--){
        int cnt=1; q[1]=0;
        sc(n); for(int i=1;i<=n;i++) scanf("%lld%lld",&A[i-1].y,&A[i].x),A[i].x+=A[i-1].x,q[++cnt]=A[i].x;
        sc(m); for(int i=1;i<=m;i++) scanf("%lld%lld",&B[i-1].y,&B[i].x),B[i].x+=B[i-1].x,q[++cnt]=B[i].x;
        sort(q+1,q+cnt+1);
        cnt=unique(q+1,q+cnt+1)-q-1;

        LL dis=3e18; r[0]=r[1]=s[0]=s[1]=0; int la=0,lb=0,fa,fb;

        A[cnt].y=B[cnt].y=0; q[cnt+1]=q[cnt]+1;
        for(int i=1;i<=cnt;i++){
            if (A[la].x==q[i]) fa=A[la++].y;else fa=A[la-1].y;
            if (B[lb].x==q[i]) fb=B[lb++].y;else fb=B[lb-1].y;
            LL x,y,t=q[i+1]-q[i];
            if(fa==fb) update(dis,dis+2,0,i);  else
            if(fa-1==fb){
                x=dis;y=dis+t;  dis+=t;
                update(x,(t&1)+y,1,i);
                update(x+1,y+1-(t&1),1,i);
            }else
            if(fa+1==fb){
                x=dis-(t-1); y=dis+1; dis-=t;
                update(x,(t&1)+y,1,i);
                update(x+1,y+1-(t&1),1,i);
            }else
            if(fa-2==fb){
                x=dis;y=dis+t*2;  dis+=t*2;
                update(x,y,1,i);
            }else
            if(fa+2&&fb){
                x=dis-t*2+2; y=dis+2; dis-=t*2;
                update(x,y,1,i);
            }
        }
        LL ans=0;
        for(int j=0;j<2;j++){
            sort(w[j]+1,w[j]+1+r[j]);
            r[j]=unique(w[j]+1,w[j]+1+r[j])-w[j]-1;
            for(int i=1;i<=r[j];i++) d[i]=0;
            for(int i=1;i<=s[j];i++){
                int x=lower_bound(w[j]+1,w[j]+r[j]+1,a[j][i])-w[j],
                	y=lower_bound(w[j]+1,w[j]+r[j]+1,b[j][i])-w[j];
                d[x]+=c[j][i];d[y]-=c[j][i];
            }
            for(int i=1;i<=r[j];i++) 
                d[i]+=d[i-1],ans=max(ans,d[i]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}