求问线段树的不同写法为什么会MLE
查看原帖
求问线段树的不同写法为什么会MLE
752441
CuFeO4楼主2024/10/21 15:56

rt

这样写是过的

#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#define Infile(x) freopen(#x".in","r",stdin)
#define Outfile(x) freopen(#x".out","w",stdout)
#define Ansfile(x) freopen(#x".ans","w",stdout)
#define Errfile(x) freopen(#x".err","w",stderr)
#ifdef LOCAL
    FILE *InFile = Infile(in),*OutFile = Outfile(out);
    // FILE *ErrFile = Errfile(err);
#else
    FILE *InFile = stdin,*OutFile = stdout;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 1e5 + 1;
#define pii pair<int,int>
#define mk make_pair
#define eb emplace_back
int n,m,k;
map<pii,int> mp;
struct DSU{
    vector<int> fa,siz;
	stack<int> sta;
    inline void init(int n){
        fa.resize(n+1);siz.resize(n+1);
        rep(i,1,n,1) fa[i] = i,siz[i] = 1;
    }
    inline int get_fa(int x){while(x ^ fa[x]) x = fa[x];return x;}
    inline bool merge(int x,int y){
        x = get_fa(x),y = get_fa(y);
        if(x == y) return false;
        if(siz[x] > siz[y]) swap(x,y);
        fa[x] = y,siz[y] += siz[x],sta.push(x);
        return true;
    }
    inline void undo(){
        int x = sta.top();sta.pop();
        siz[fa[x]] -= siz[x],fa[x] = x;
    }
    inline void undo(int res){while(sta.size() > res) undo();}
}D;
struct Segment_Tree_Divide{
	struct node{
		int l,r;
    	vector<pii> v;
	}t[N<<2];
	void B(int k,int l,int r){
		t[k].l = l,t[k].r = r;
		vector<pii> ().swap(t[k].v);
		if(l == r) return;
		int mid = (l + r) >> 1;
		B(k<<1,l,mid);B(k<<1|1,mid+1,r);
	}
    void I(int k,int ql,int qr,int x,int y){
        if(ql <= t[k].l && t[k].r <= qr) return t[k].v.eb(mk(x,y));
        int mid = (t[k].l + t[k].r) >> 1;
        if(ql <= mid) I(k<<1,ql,qr,x,y);
        if(qr > mid) I(k<<1|1,ql,qr,x,y);
    }
    void Q(int k){
        int bk = D.sta.size();
        bool flag = false;
        for(auto i:t[k].v){
            bool pd = !D.merge(i.first,i.second);
            flag |= pd;
            if(flag){
                rep(i,t[k].l,t[k].r,1) cout<<"Yes\n";
                break;
            }
        }
        if(!flag){
            if(t[k].l == t[k].r) cout<<"No\n";
            else Q(k<<1),Q(k<<1|1);
        }
        D.undo(bk);
    }
}T;
inline void solve(){
    cin>>n>>m;D.init(n+n);
    rep(i,1,m,1){
        int x,y;cin>>x>>y;
        mp[mk(x,y)] = 1;
    }
    cin>>k;T.B(1,1,k);
    rep(i,1,k,1){
        int x,y;cin>>x>>y;
        if(mp.find(mk(x,y)) != mp.end()){
            T.I(1,mp[mk(x,y)],i-1,x,y+n);
            mp.erase(mk(x,y));
        }
        else mp[mk(x,y)] = i;
    }
    for(auto i:mp) T.I(1,i.second,k,i.first.first,i.first.second+n);
    T.Q(1);
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    solve();
}

这样写是MLE的,两篇代码的区别仅在于上面那篇是用了一个结构体保存了左右端点,下面这篇直接在递归中传参。

#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#define Infile(x) freopen(#x".in","r",stdin)
#define Outfile(x) freopen(#x".out","w",stdout)
#define Ansfile(x) freopen(#x".ans","w",stdout)
#define Errfile(x) freopen(#x".err","w",stderr)
#ifdef LOCAL
    FILE *InFile = Infile(in),*OutFile = Outfile(out);
    // FILE *ErrFile = Errfile(err);
#else
    FILE *InFile = stdin,*OutFile = stdout;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 1e5 + 1;
#define pii pair<int,int>
#define mk make_pair
#define eb emplace_back
int n,m,k;
map<pii,int> mp;
struct DSU{
    vector<int> fa,siz;
	stack<int> sta;
    inline void init(int n){
        fa.resize(n+1);siz.resize(n+1);
        rep(i,1,n,1) fa[i] = i,siz[i] = 1;
    }
    inline int get_fa(int x){while(x ^ fa[x]) x = fa[x];return x;}
    inline bool merge(int x,int y){
        x = get_fa(x),y = get_fa(y);
        if(x == y) return false;
        if(siz[x] > siz[y]) swap(x,y);
        fa[x] = y,siz[y] += siz[x],sta.push(x);
        return true;
    }
    inline void undo(){
        int x = sta.top();sta.pop();
        siz[fa[x]] -= siz[x],fa[x] = x;
    }
    inline void undo(int res){while(sta.size() > res) undo();}
}D;
struct Segment_Tree_Divide{
    vector<pii> t[N<<2];
    void I(int k,int l,int r,int ql,int qr,int x,int y){
        if(ql <= l && r <= qr) return t[k].eb(mk(x,y));
        int mid = (l + r) >> 1;
        if(ql <= mid) I(k<<1,l,mid,ql,qr,x,y);
        if(qr > mid) I(k<<1|1,mid+1,r,ql,qr,x,y);
    }
    void Q(int k,int l,int r){
        int bk = D.sta.size();
        bool flag = false;
        for(auto i:t[k]){
            bool pd = !D.merge(i.first,i.second);
            flag |= pd;
            if(flag){
                rep(i,l,r,1) cout<<"Yes\n";
                break;
            }
        }
        if(!flag){
            if(l == r) cout<<"No\n";
            else{
                int mid = (l + r) >> 1;
                Q(k<<1,l,mid);Q(k<<1|1,mid+1,r);
            }
        }
        D.undo(bk);
    }
}T;
inline void solve(){
    cin>>n>>m;D.init(n+n);
    rep(i,1,m,1){
        int x,y;cin>>x>>y;
        mp[mk(x,y)] = 1;
    }
    cin>>k;
    rep(i,1,k,1){
        int x,y;cin>>x>>y;
        if(mp.find(mk(x,y)) != mp.end()){
            T.I(1,1,k,mp[mk(x,y)],i-1,x,y+n);
            mp.erase(mk(x,y));
        }
        else mp[mk(x,y)] = i;
    }
    for(auto i:mp) T.I(1,1,k,i.second,k,i.first.first,i.first.second+n);
    T.Q(1,1,k);
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    solve();
}
2024/10/21 15:56
加载中...