借用了逆十字的代码,然后加入了自己的一些理解。

#include<bits/stdc++.h>

using namespace std;

const int N=100005;

#define PII pair<int,int> 
// #define x first 
// #define y second

vector<PII> op0[N],op1[N];
int n,D,t[N<<2],tg[N<<2];

void change(int k,int l,int r,int x,int y,int v)
{
    if(x<=l&&r<=y){
        t[k]+=v;tg[k]+=v;return;//懒惰标记
    }
    int mid=(l+r)>>1;
    if(x<=mid) change(k<<1,l,mid,x,y,v);
    if(y>mid) change(k<<1|1,mid+1,r,x,y,v);
    t[k]=min(t[k<<1],t[k<<1|1])+tg[k];//+tg[k]其实就是把懒惰标记下传//更新父结点信息。
}

int ask(int k,int l,int r)
{
    if(l==r) return l;
    int mid=(l+r)/2;
//因为要找到一个结点t[k]=0。t[k]!=0;
    if(tg[k]+t[k<<1]==t[k]){
        return ask(k<<1,l,mid);
    }
    return ask(k<<1|1,mid+1,r);
}

int main()
{
    scanf("%d%d",&n,&D);
    int del=(1<<30)/D*D;
    for(int i=1;i<=n;i++){
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        x1+=del,x2+=del,y1+=del,y2+=del;
        vector<PII> _x,_y;
        if(x2-x1>=D){
            _x.push_back({0,D-1});
        }
        else if((x2-1)%D>=x1%D){
            _x.push_back({x1%D,(x2-1)%D});
        }
        else{
            _x.push_back({x1%D,D-1});
            _x.push_back({0,(x2-1)%D});
        }
                //这里后一个减一是为了防止 1-5 5-8被覆盖了两次,改成1-4,5-7就不会了。
        if(y2-y1>=D){
                        //全部覆盖
            _y.push_back({0,D-1});
        }
        else if((y2-1)%D>=y1%D){
                        //一段覆盖
            _y.push_back({y1%D,(y2-1)%D});
        }
        else{
                        //两端覆盖
            _y.push_back({y1%D,D-1});
            _y.push_back({0,(y2-1)%D});
        }
        for(auto j:_x)
            for(auto k:_y){
                                //分开op0是入边,op1是出边
                op0[j.first].push_back(k);
                op1[j.second+1].push_back(k);//这里加1是因为你取模放的时候减了1。
            }
//这里处理其实x不太重要,重要的是y,不是说重要不重要,就是偏重。
    }
    for(int i=0;i<D;i++){
                //更新覆盖区域  
                //入边。
        for(auto j:op0[i]){
            change(1,0,D-1,j.first,j.second,1);
        }
        // 出边
        for(auto j:op1[i]){
            change(1,0,D-1,j.first,j.second,-1);
        }
                //    
        if(t[1]==0){
            puts("YES");
            cout<<i<<" "<<ask(1,0,D-1)<<endl;return 0;
        }
    }
    puts("NO");
}