CF1214G Feeling Good 题解

题目链接

点击打开链接

题目解法

我真菜啊,感觉每一步都不难,但一步都没想到/yun

考虑两行 \(x,y\) 什么时候可以构造出合法的矩形?
\(x\) 中需要有 \(y\) 对应位置为 \(0\)\(1\)\(y\) 中需要有 \(x\) 对应位置为 \(0\)\(1\)
归纳一下,\(x\) 不是 \(y\) 的子集 且 \(y\) 不是 \(x\) 的子集

我先想的是:是否只需要考虑相邻两行,但这显然是错的
事实上,只要拓展一下,把行按照行内 \(1\) 的个数排序,我们只需要考虑排序之后的相邻两行即可,证明也是显然的

我们用 \(bitset\) 维护一行的信息,\(set\) 维护排序之后的序列 就做完了
时间复杂度 \(O(nq\log n+\frac{n^2q}{64})\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=2010;
int n,m,q;
bitset<N> bs[N],dif,tmp;
set<pii> S;
set<pii> mat;
#define fi first
#define se second
bool chk(int a,int b){
    dif=bs[a]^bs[b];
    return (bs[a]&dif).any()&&(bs[b]&dif).any();
}
void del(int a){
    auto it=S.find({bs[a].count(),a});
    int prv=-1,nxt=-1;
    if(it!=S.begin()) prv=(*prev(it)).se;
    if(next(it)!=S.end()) nxt=(*next(it)).se;
    if(prv!=-1&&mat.find({prv,a})!=mat.end()) mat.erase({prv,a});
    if(nxt!=-1&&mat.find({a,nxt})!=mat.end()) mat.erase({a,nxt});
    if(prv!=-1&&nxt!=-1&&chk(prv,nxt)) mat.insert({prv,nxt});
    S.erase(it);
}
void ins(int a){
    auto it=S.insert({bs[a].count(),a}).first;
    int prv=-1,nxt=-1;
    if(it!=S.begin()) prv=(*prev(it)).se;
    if(next(it)!=S.end()) nxt=(*next(it)).se;
    if(prv!=-1&&nxt!=-1&&mat.find({prv,nxt})!=mat.end()) mat.erase({prv,nxt});
    if(prv!=-1&&chk(prv,a)) mat.insert({prv,a});
    if(nxt!=-1&&chk(a,nxt)) mat.insert({a,nxt});
}
int main(){
    read(n),read(m),read(q);
    F(i,1,n) S.insert({0,i});
    F(i,1,q){
        int a,x,y;read(a),read(x),read(y);
        del(a);
        tmp.set();tmp>>=N-(y-x+1),tmp<<=x;
        bs[a]^=tmp;
        ins(a);
        if(!mat.empty()){
            auto [a,b]=*mat.begin();
            if(a>b) swap(a,b);
            dif=bs[a]^bs[b];
            int ans1=(bs[a]&dif)._Find_first(),ans2=(bs[b]&dif)._Find_first();
            if(ans1>ans2) swap(ans1,ans2);
            printf("%d %d %d %d\n",a,ans1,b,ans2);
        }
        else puts("-1");
    }
    return 0;
}

posted @ 2024-10-01 17:44  Farmer_D  阅读(19)  评论(0)    收藏  举报