并查集
合并集合,判断连通块中点的数量,判断集合中是否有环(只能用于无向图)等
int fa[N],n,m;
bool flag;
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main(){
cin>>n>>m;
rep(i,1,n) fa[i]=i;//
while(m--){
int a,b,op;
cin>>op>>a>>b;
a=find(a),b=find(b);
if(op==1){
if(a==b && !flag) flag=1;
fa[b]=a;
}
else{
if(a==b) cout<<"Y\n";
else cout<<"N\n";
}
}
// judge round
if(flag) cout<<"Yes\n";
else cout<<"No\n";
return 0;
}
4 8
1 4 5
1 1 2
2 3 5
1 3 4
1 2 3
1 1 5
2 1 4
2 3 5
线段树
点修改
区间-查询
记得要加
pushdown
区间-修改
懒标记
有助于降低时间复杂度
Code模板
#define int long long
const int N = 1e5 + 10, mod = 998244353;
#define lc p<<1
#define rc p<<1|1
int n,m,w[N];
struct node{
int l,r,sum,add;
}tr[N*4];
void pushup(int p){
tr[p].sum=tr[lc].sum+tr[rc].sum;
}
void pushdown(int p){
if(tr[p].add){
tr[lc].sum+=tr[p].add*(tr[lc].r-tr[lc].l+1);//beware:add
tr[rc].sum+=tr[p].add*(tr[rc].r-tr[rc].l+1);//
tr[lc].add+=tr[p].add;
tr[rc].add+=tr[p].add;
tr[p].add=0;
}
}
void build(int p,int l,int r){
tr[p]={l,r,w[l],0};
if(l==r) return;
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pushup(p);
}
void update(int p,int x,int y,int k){
if(tr[p].l>=x && tr[p].r<=y){
tr[p].sum+=(tr[p].r-tr[p].l+1)*k;
tr[p].add+=k;
return;
}
int m=tr[p].l+tr[p].r>>1;
pushdown(p);
if(x<=m) update(lc,x,y,k);
if(y>m) update(rc,x,y,k);
pushup(p);
}
int query(int p,int x,int y){
if(tr[p].l>=x && tr[p].r<=y) return tr[p].sum;
int m=tr[p].l+tr[p].r>>1;
pushdown(p);
int cnt=0;
if(x<=m) cnt+=query(lc,x,y);//beware
if(y>m) cnt+=query(rc,x,y);
return cnt;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m;
rep(i,1,n) cin>>w[i];
build(1,1,n);
while(m--){
int op,k,x,y;
cin>>op>>x>>y;
if(op==2) cout<<query(1,x,y)<<endl;
else cin>>k,update(1,x,y,k);
}
return 0;
}