线段树分治
模板
#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
":"Yes
");
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
",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