int n, m; int a[N]; int fa[N]; int nx[N]; int get(int x) { return x == fa[x] ? x : fa[x] = get(fa[x]) ; } void solve(){ int q;cin>>n>>q; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)fa[i]=i,nx[i]=i+1; for(int i=1;i<=q;i++){ int op;cin>>op; if(op==1){ int l,r;cin>>l>>r; int g; while(nx[get(l)]<=r){// //我们只关注当前点所在的集合根,所以get(L); //看这个集合最多已经合并到哪,下一个要更新的点是谁 //,使用nx[get(l)],如果大于r,说明这段河流挡板已经被打开过了
现在有 n 片雪花排成一列。 pty 要对雪花进行 m 次染色操作,第 i 次染色操作中,把第 ((i×p+q)modn)+1 片雪花和第 ((i×q+p)modn)+1 片雪花之间的雪花(包括端点)染成颜色 i。其中 p,q 是给定的两个正整数。他想知道最后 n 片雪花被染成了什么颜色。没有被染色输出 0。
// Problem: P2391 白雪皑皑 // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P2391 // Memory Limit: 125 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h> using namespace std; #define ll long long //# define int long long #define ull unsigned long long #define pii pair<int,int>
#define baoliu(x, y) cout << fixed << setprecision(y) << x #define endl "\n" #define debug1(x) cerr<<x<<" " #define debug2(x) cerr<<x<<endl const int N = 1e6 + 10; const int M = 1e6 + 10; const int inf = 0x3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; int n, m; int a[N]; int f[N]; int nx[N]; int ans[N];
//f[x]表示x后第一个可操作的节点。 int find(int x) { return x == f[x] ? x : f[x] = find(f[x]) ; } void solve(){ int q,p; cin>>n>>m>>p>>q; for(int i=1;i<=n;i++)f[i]=i; f[n+1]=n+1; for(int i=m;i>=1;i--){ int tl=(i*p+q)%n+1; int tr=(i*q+p)%n+1; int l=min(tl,tr); int r=max(tl,tr); int j=l; while(j<=r){ //下一个没被染色的点 int tmp=find(j);//看一下j的根,也是下一个没被染色的点 if(tmp==j){//根是自己,说明之前没染色 ans[j]=i; f[j]=find(j+1);//染色了,维护这个关系。把j指向j+1的根节点 } //j=tmp; j=f[j];//j跳到下一个没被染色的点 if(j==n+1)break;//这里要注意,不然越界死循环,需要提前预处理一下 } } for(int i=1;i<=n;i++)cout<<ans[i]<<endl; }
int main() { cin.tie(0); ios::sync_with_stdio(false);
int t; //cin>>t; t=1; while (t--) { solve(); } return 0; }
2024迎新春多校G
在一个一维坐标轴上有 n 个点,坐标分别为 1,2,...,n−1,n。 初始的时候每个点上都有一个障碍物,坐标为 i上的障碍物坚固程度为 ai。 现在Bingbong有 m 次操作或者询问:
int n, m; int a[N]; int f[N]; int find(int x){ if(f[x]==x)return f[x]; f[x]=find(f[x]); return f[x]; } void solve(){ cin>>n;cin>>m; for(int i=1;i<=n;i++)f[i]=i; f[n+1]=n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=m;i++){ int op;cin>>op; if(op==2){ int pos;cin>>pos; f[pos]=find(pos);//这步很重要,在查询前要处理子节点 cout<<f[pos]<<endl; } else { int pos,x;cin>>pos>>x; a[pos]-=x; if(a[pos]<=0){ f[pos]=find(f[pos+1]);//合并的时候只维护了根节点得关系 } } } }