1 条题解

  • 0
    @ 2026-4-23 23:39:50

    挺好的题。

    首先,没有被任何矩形覆盖的各自随便决定放或不放,快速幂最后乘一下就好了。

    我们不难发现若一个矩形被另一个矩形所包含,那么另一个矩形的限制就没有意义了,也就是横坐标纵坐标同时大于另一矩形的矩形我们可以直接忽略。这样我们就把所有矩形转化为了横坐标递增,纵坐标递减的类型,如果这里看不懂可以画一画样例。

    接下来不难发现,一个格子若被多个矩形包含,则一定会被包含在一段连续的矩形当中,因为如果一个矩形不包含它,那么一定是纵坐标小了或横坐标小了,然而我们有单调性,越左越右肯定会越变越差,所以是连续的。

    接下来我们可以考虑动态规划了,我们考虑状态为只考虑前 ii 个限制的方案数。

    考虑转移,我们有两种选择,一种是根本不在这个矩形中放,这种直接由前一个状态转移来即可,另一种是放了,如果放在与其他矩形相交的地方了,我们肯定要求所有包含这一点矩形什么都不能放。

    我们之前发现的性质是与其相交的矩形一定是连续的,我们不妨钦定与其相交的矩形是从 jjii 的所有矩形,而其他矩形不能包含这个点,这样我们对这样的点数计数,乘到 j1j-1 的状态上,也就达成了 jji1i-1 什么都不放的诉求。

    我们已经有一个时间复杂度平方的算法了,我们更进一步,发现这个点数计数我们既有关于转移点的信息,又有关于被转移点的信息,这太讨厌了,但是仔细看就会发现,被转移点只和纵坐标有关,转移点只和横坐标有关,我们不妨把纵坐标提出来,然后前缀和维护动态规划值和横坐标的乘积,具体的:

    fi=fi1+sum×(cici+1)f_i=f_{i-1}+sum\times (c_i-c_{i+1})%mod sum=sum+fi×(ri+1ri)sum=sum+f_i\times (r_{i+1}-r_i)

    我们这题就愉快的通过了。

    #include<bits/stdc++.h>
    using namespace std;
    namespace MyGO{
        #define int long long
        bool NagasakiSoyo;
        const int INF=0x3f3f3f3f3f3f3f3f;
        const int mod=1e9+7;
        struct Sqr{ int r,c; } a[210000],b[210000];
        int f[210000];
        int qpow(int x,int y){
            int res=1;
            while(y){
                if(y&1) res=res*x%mod;
                x=x*x%mod;y>>=1;
            }
            return res;
        }
        bool ChihayaAnon;
        void main(){
            cerr<<((&NagasakiSoyo)-(&ChihayaAnon))/1048576.0<<'\n';
            // freopen("data.in","r",stdin);
            // freopen("data.out","w",stdout);
            int n,m;cin>>n>>m;
            for(int i=1;i<=n;i++) cin>>a[i].r>>a[i].c;
            sort(a+1,a+n+1,[&](Sqr X,Sqr Y){ return X.r<Y.r; });
            deque<int> s;
            for(int i=1;i<=n;i++){
                while((not s.empty()) and (a[s.back()].c<a[i].c)) s.pop_back();
                s.push_back(i);
            }
            n=0;int K=0;
            while(not s.empty()){
                b[++n]=a[s.front()];
                s.pop_front();
                K=K+(b[n].r-b[n-1].r)*(m-b[n].c);
            }
            K=K+(m-b[n].r)*m;
            K=qpow(2,K);
            int sum=0;f[0]=1;sum=sum+b[1].r;
            for(int i=1;i<=n;i++){
                f[i]=f[i-1]+sum*(b[i].c-b[i+1].c)%mod;f[i]%=mod;
                sum=sum+f[i]*(b[i+1].r-b[i].r)%mod;sum%=mod;
            }
            cout<<f[n]*K%mod<<'\n';
            cerr<<1.0*clock()/CLOCKS_PER_SEC*1000.0<<'\n';
        }
        #undef int
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        MyGO::main();
        return 0;
    }
    
    • 1

    信息

    ID
    9648
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者