线段树分治

线段树分治

模板

#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int N=4e5+5;
#define ls (p<<1)
#define rs (p<<1|1)
inline int read() {
	int x=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return x;
}
int fa[N],d[N];
int n,m,k;
struct Tree{
	int l,r;
	Tree(){}
	Tree(int L,int R):l(L),r(R){}
}t[N<<2];

vector<Tree>v[N];
void build(int l,int r,int p) {
	t[p].l=l,t[p].r=r;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(l,mid,ls);
	build(mid+1,r,rs);
}
void modify(int L,int R,int x,int y,int p) {
	if(t[p].l>R||t[p].r<L) return;
	if(L<=t[p].l&&t[p].r<=R) {
		v[p].push_back(Tree(x,y));
		return;
	}
	modify(L,R,x,y,ls);
	modify(L,R,x,y,rs);
}

struct node{
	int depf,dep,fr,to;
	node(){}
	node(int fr_,int to_,int depf_,int dep_):fr(fr_),to(to_),depf(depf),dep(depf_){}
}st[N];
int tp;
inline int find(int x) {
	for(;x!=fa[x];x=fa[x]);
	return fa[x];
}
void merge(int x,int y) {
	int fx=find(x),fy=find(y);
	if(fx==fy) return;
	st[++tp]=node(fx,fy,d[fx],d[fy]);
	if(d[fx]<d[fy]) fa[fx]=fy,d[fy]=max(d[fy],d[fx]+1);
	else fa[fy]=fx,d[fx]=max(d[fx],d[fy]+1);
}
void recover(int x) {
	while(tp>x) {
		fa[st[tp].fr]=st[tp].fr;fa[st[tp].to]=st[tp].to;
		d[st[tp].fr]=st[tp].depf;d[st[tp].to]=st[tp].dep;
		--tp;
	}
}
bool ans[N];
void dfs(int p) {
	for(int i=0;i<v[p].size();i++) {
		int x=v[p][i].l,y=v[p][i].r;
		merge(x,y+n);
		merge(x+n,y);
		if(find(x)==find(x+n)||find(y)==find(y+n)) {
			for(int i=t[p].l;i<=t[p].r;i++)
				ans[i]=1;
			return;
		}
	}
	if(t[p].l==t[p].r) return;
	int now=tp;
	dfs(ls);
	recover(now);
	dfs(rs);
	recover(now);
}

int main() {
	n=read();m=read();k=read();
	for(int i=1;i<=2*n;i++) fa[i]=i,d[i]=1;
	build(1,k,1);
	for(int i=1,u,v,l,r;i<=m;i++) {
		u=read();v=read();l=read();r=read();
		if(l!=r) modify(l+1,r,u,v,1);//从l+1开始有 
	} 
	dfs(1);
	for(int i=1;i<=k;i++)
		printf(ans[i]?"No\n":"Yes\n");
	return 0;
}

https://www.luogu.com.cn/blog/_post/199068

考试题

#include <cstdio>
#include <vector>
#include <cstring>
#include <utility>
#include <iostream>
#include <algorithm>
#define N 300010
#define ls (p<<1)
#define rs (p<<1|1)
#define mid ((l+r)>>1)
using namespace std;
inline int read() {
	int x=0,f=1;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;
}
int n,m,cnt,sum;
int q[N],ans[N],f[N],size[N],p1[N],p2[N];
struct node{
	int x,y,t1,t2,v;
	node(){}
	node(int x_,int y_,int t1_,int t2_,int v_):x(x_),y(y_),t1(t1_),t2(t2_),v(v_){}
}st[N];
struct Tree{
	int l,r;
	Tree(){} 
	Tree(int l_,int r_):l(l_),r(r_){}
}t[N];
vector<Tree> v[N];
int hd[N],to[N],nxt[N],tot;
inline void add(int x,int y) {
	to[++tot]=y;nxt[tot]=hd[x];hd[x]=tot;
}

int fa[N],son[N],siz[N],dep[N];
void dfs_son(int x,int f) {
	fa[x]=f;dep[x]=dep[f]+1;siz[x]=1;
	for(int i=hd[x];i;i=nxt[i]) {
		int y=to[i];
		if(y==f) continue;
		dfs_son(y,x);
		siz[x]+=siz[y];
		if(siz[y]>siz[son[x]]) son[x]=y;
	}
}
int top[N];
void dfs_chain(int x,int tp) {
	top[x]=tp;
	if(son[x]) dfs_chain(son[x],tp);
	for(int i=hd[x];i;i=nxt[i]) {
		int y=to[i];
		if(y==fa[x]||y==son[x]) continue;
		dfs_chain(y,y);
	}
}
inline int dis(int x,int y) {
	int res=dep[x]+dep[y];
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	int lca=dep[x]<dep[y]?x:y;
	return res-2*dep[lca];
}
int find(int x){
    return f[x]==x?x:find(f[x]);
}
void merge(int x,int y) {
	x=find(x),y=find(y);
	if(size[x]<size[y]) swap(x,y);
	st[++cnt]=node(x,y,p1[x],p2[x],sum);
	int t1=p1[x],t2=p2[x],len=dis(t1,t2),l;
	
	l=dis(p1[y],p2[y]);
	if(l>len) t1=p1[y],t2=p2[y],len=l;
	l=dis(p1[x],p2[y]);
	if(l>len) t1=p1[x],t2=p2[y],len=l;
	l=dis(p1[y],p2[x]);
	if(l>len) t1=p1[y],t2=p2[x],len=l;
	l=dis(p1[x],p1[y]);
	if(l>len) t1=p1[x],t2=p1[y],len=l;
	l=dis(p2[x],p2[y]);
	if(l>len) t1=p2[x],t2=p2[y],len=l;	
	sum=max(sum,len),p1[x]=t1,p2[x]=t2,size[x]+=size[y],f[y]=x;
}
void del(int id) {
    int x=st[id].x,y=st[id].y;
    f[y]=y,size[x]-=size[y],p1[x]=st[id].t1,p2[x]=st[id].t2,sum=st[id].v;
}

void modify(int L,int R,int l,int r,int x,int y,int p) {
    if(L<=l&&R>=r) {
        v[p].push_back({x,y});
        return;
    }
    if(L<=mid) modify(L,R,l,mid,x,y,ls);
    if(R>mid) modify(L,R,mid+1,r,x,y,rs);
}
void dfs(int l,int r,int p) {
    int now=cnt;
    for(int i=0;i<v[p].size();++i) merge(v[p][i].l,v[p][i].r);
    if(l==r) ans[l]=sum;
    else dfs(l,mid,ls),dfs(mid+1,r,rs);
    while(cnt>now) del(cnt--);
}
int main() {
	freopen("2.in","r",stdin);
	freopen("1.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;++i) f[i]=p1[i]=p2[i]=i,siz[i]=1;
    for(int i=1;i<n;++i) {
        int x,y,l,r;
        x=read(),y=read(),l=read(),r=read();
        add(x,y),add(y,x),modify(l,r,1,n,x,y,1);
    }
    for(int i=1;i<=m;++i) q[i]=read();
    dfs_son(1,0),dfs_chain(1,1),dfs(1,n,1);
    for(int i=1;i<=m;++i) printf("%d\n",ans[q[i]]);
    return 0;
}

一些难题

https://www.cnblogs.com/huyufeifei/p/10417540.html

  • CF1140F

  • P5227

  • P4585

  • CF576E

  • [HAOI2017]八纵八横

    [SHOI2014]神奇化合物

    [APIO2018]New Home 新家

    [CF678F]Lena and Queries

    [bzoj4311]向量

    [bzoj4184]shallot

posted @ 2020-09-17 21:21  ke_xin  阅读(43)  评论(0编辑  收藏  举报