CodeForces 828C String Reconstruction(並查集思想)
阿新 • • 發佈:2018-08-22
ack return set bsp amp turn struct ++ color
題意:給你n個串,給你每個串在總串中開始的每個位置,問你最小字典序總串。
思路:顯然這道題有很多重復填塗的地方,那麽這裏的時間花費就會特別高。
我們維護一個並查集fa,用fa[i]記錄從第i位置開始第一個沒填塗的位置,那每次都能跳過塗過的地方。每次填完當前格就去填find(fa[i + 1])。
ps:一定要合並,不然超時。
代碼:
#include<stack> #include<vector> #include<queue> #include<set> #include<cstring> #include<string> #include<sstream> #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #define ll long long #define ull unsigned long long using namespace std; const int maxn = 1000000+5; const int seed = 131; const int MOD = 100013; const int INF = 0x3f3f3f3f; char ans[maxn*10]; int fa[maxn*10]; char s[maxn]; int find(int x){ return fa[x] == x? x : fa[x] = find(fa[x]); } int main(){ int n,t; memset(ans,0,sizeof(ans)); scanf("%d",&n); for(int i = 0;i < maxn * 10;i++) fa[i] = i; int end = 1; while(n--){ scanf("%s%d",s,&t); int len = strlen(s);while(t--){ int x; scanf("%d",&x); end = max(end,x + len - 1); for(int i = find(x);i <= x + len -1;i = find(i + 1)){ ans[i] = s[i - x]; int fx = find(i); int fy = find(i + 1); if(fx > fy) fa[fy] = fx; else fa[fx] = fy; } } } for(int i = 1;i <= end;i++) if(ans[i] != 0)printf("%c",ans[i]); else printf("a"); printf("\n"); return 0; }
CodeForces 828C String Reconstruction(並查集思想)