抱铃求助

P5787 二分图 /【模板】线段树分治

```cpp #include <bits/stdc++.h> #define _cst const #define _IfD long long #define _siz 20 char buf[1<<_siz],buffer[1<<_siz],*p1=buf,*p2=buf,c=' '; int op1=-1; _cst int op2=(1<<_siz)-1; inline char gc(){return (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<_siz,stdin)),p1==p2?EOF:*p1++);} inline void flush(){fwrite(buffer,1,op1+1,stdout),op1=-1;} inline void pc(_cst char &x){if(op1==op2)flush();buffer[++op1]=x;} template<typename T>void read(T &w){ w=0;bool f=1;char ch=gc(); for(;ch<=32;ch=gc()); if(ch=='-')f=0; for(;'0'<=ch && ch<='9';ch=gc()) w=(w<<1)+(w<<3)+(ch^48); w=f?w:-w; }template<typename T,typename ...Arg>void read(T &w,Arg &...arg){ read(w); read(arg...); }template<typename T>void wrt(T x){ if(x<0) pc('-'),x=-x; if(x>9) wrt(x/10); pc(x%10|48); }template<typename T>void write(T x){ wrt(x); pc(c); }template<typename T,typename ...Arg>void write(T x,Arg ...arg){ write(x); write(arg...); }inline _IfD pow_10(_IfD x){ _IfD base=10,ans=1; while(x) ans*=((x&1)?base:1),base*=base,x>>=1; return ans; }template<typename T>void readd(T &w){ w=0; _IfD x=0,cnt=0; bool f=1; char ch=gc(); for(;ch<=32;ch=gc()); if(ch=='-')f=0; for(;'0'<=ch && ch<='9';ch=gc()) x=(x<<1)+(x<<3)+(ch^48); w=(T)(f?x:-x); if(ch!='.') return; x=0,ch=gc(); for(;'0'<=ch && ch<='9';ch=gc(),++cnt) x=(x<<1)+(x<<3)+(ch^48); T tmp=(T)(x/(T)pow_10(cnt)); w=w+(T)(f?tmp:-tmp); }template<typename T,typename ...Arg>void readd(T &w,Arg &...arg){ readd(w); readd(arg...); } template<typename T>inline T qmax(_cst T &a,_cst T &b){return a>b?a:b;} template<typename T,typename ...Arg>inline T qmax(_cst T &a,_cst T &b,_cst Arg &...arg){return qmax(a,qmax(b,arg...));} template<typename T>inline T qmin(_cst T &a,_cst T &b){return a<b?a:b;} template<typename T,typename ...Arg>inline T qmin(_cst T &a,_cst T &b,_cst Arg &...arg){return qmin(a,qmin(b,arg...));} template<typename T>inline void qswap(T &a,T &b){a+=b,b=a-b,a-=b;} using namespace std; const int MAXN=100005; int n,m,k; int fa[MAXN<<1],d[MAXN<<1]; int find(int k){return (fa[k]==k?k:find(fa[k]));} struct Edge{int u,v,ud,vd,id;}; stack<Edge> s; inline void Merge(int x,int y,int id){ if(x==y) return; if(d[x]>d[y]) qswap(x,y); s.push((Edge){x,y,d[x],d[y],id}); fa[x]=y; d[y]+=(d[x]==d[y]); } vector<pair<int,int> > tr[MAXN<<2]; void upd(int p,int l,int r,int st,int en,int x,int y){ if(l>en || r<st) return; if(st<=l && r<=en){ tr[p].push_back(make_pair(x,y)); return; } int mid=(l+r)>>1; upd(p<<1,l,mid,st,en,x,y); upd(p<<1|1,mid+1,r,st,en,x,y); } void solve(int p,int l,int r){ bool f=1; for(pair<int,int> t:tr[p]){ int u=t.first,v=t.second; if(find(u)==find(v)){ for(int i=l;i<=r;i++) pc('N'),pc('o'),pc(10); f=0; break; } Merge(find(u),find(v+n),p); Merge(find(u+n),find(v),p); } if(f){ if(l==r){ pc('Y'),pc('e'),pc('s'),pc(10); return; } int mid=(l+r)>>1; solve(p<<1,l,mid); solve(p<<1|1,mid+1,r); } while(!s.empty() && s.top().id==p){ Edge x=s.top(); s.pop(); fa[x.u]=x.u; d[x.v]=x.vd; } } int main(){ read(n,m,k); for(int i=1;i<=(n<<1);i++) fa[i]=i,d[i]=1; for(int i=1;i<=m;i++){ int x,y,l,r; read(x,y,l,r); upd(1,1,k,l+1,r,x,y); } solve(1,1,k); return flush(),0; } ```
by E1_de5truct0r @ 2023-01-29 22:05:24


什么题
by hyh_Windows11 @ 2023-01-29 22:09:43


@[hyh_Windows11](/user/890617) 睁大眼睛,右边,P5787 二分图 / 【模板】线段树分治
by __er @ 2023-01-29 22:15:25


@[hyh_Windows11](/user/890617) 眼睛是个好东西捏。
by RP_INT_MAX @ 2023-01-29 22:17:33


我游戏老寒腿+火眼金睛
by hyh_Windows11 @ 2023-01-29 22:18:46


```cpp #include<bits/stdc++.h> using namespace std; const int N = 10101010; int read(){ int x = 0,f = 0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=1; ch=getchar(); } while(isdigit(ch)){x=x*10+ch-'0'; ch=getchar(); } return f?-x:x; } int n,m,k,fa[N],height[N],top; struct E{int x,y;}e[N]; struct Stack{int x,y,add;}st[N]; vector<int> t[N]; int findfa(int x) { while(x != fa[x]) x = fa[x]; return fa[x]; } void debug() { printf("\n****************\n下标"); for(int i = 1;i <= n*2;i++) printf("%d ",i); printf("\n父亲"); for(int i = 1;i <= n*2;i++) printf("%d ",fa[i]); printf("\n祖先(代表元)"); for(int i = 1;i <= n*2;i++) printf("%d ",findfa(i)); } void merge(int x,int y) { int fx = findfa(x),fy = findfa(y); if(height[fx] > height[fy]) swap(fx,fy); st[++top] = (Stack){fx,fy,height[fx] == height[fy]}; fa[fx] = fy; if(height[fx] == height[fy]) height[fy]++; } void update(int u,int l,int r,int L,int R,int x) { if(l > R || r < L) return; if(L <= l && r <= R) {t[u].push_back(x); return; } int mid = l + r >> 1; update(u<<1,l,mid,L,R,x); update(u<<1|1,mid+1,r,L,R,x); } void solve(int u,int l,int r) { // debug(); int ans = 1; int lasttop = top; for(int i = 0;i < t[u].size();i++) { int a = findfa(e[t[u].at(i)].x); int b = findfa(e[t[u].at(i)].y); if(a == b) { for(int k = l;k <= r;k++) printf("No\n"); ans = 0; break; } merge(e[t[u].at(i)].x,e[t[u].at(i)].y+n); merge(e[t[u].at(i)].y,e[t[u].at(i)].x+n); } if(ans) { if(l==r) printf("Yes\n"); else { int mid = l+r>>1; solve(u<<1,l,mid); solve(u<<1|1,mid+1,r); } } while(top > lasttop) { height[fa[st[top].x]] -= st[top].add; fa[st[top].x] = st[top].x; top--; } return; } int main() { n = read();m = read();k = read(); for(int i = 1;i <= m;i++) { e[i].x = read();e[i].y = read(); int l = read()+1,r = read(); update(1,1,k,l,r,i); } for(int i = 1;i <= 2*n;i++) fa[i] = i,height[i] = 1; solve(1,1,k); return 0; } ```
by hyh_Windows11 @ 2023-01-29 22:23:06


可以了吧
by hyh_Windows11 @ 2023-01-29 22:23:30


@[hyh_Windows11](/user/890617) 打几个换行无法掩盖这是tj的事实
by yinhee @ 2023-01-29 22:26:46


@[El_destructor](/user/195198) 我 $0 \rightarrow 80$ 的改动是: ```cpp merge(i.first, N + find(i.second)), merge(i.second, N + find(i.first)); ``` (merge 里面再 find 一次。) 希望对您有帮助。
by FGgirl @ 2023-01-29 22:27:06


操你妈难绷,帮你改完这个 tle 了
by FGgirl @ 2023-01-29 22:28:23


| 下一页