题目链接: http://codeforces.com/contest/828/problem/C
或许对于我来说的玄学做法你们并不在意。
题目大意很清楚,就是构建一个字典序最小的字符串满足给出的几个要求。直接暴力肯定不行,想优化怎么也想不出来,偶然看到一AC的代码感觉非常厉害,按照思路自己写了一遍。
大体思路:每次将子串加入结果串的时候利用并查集的思想(个人见解)将整个子串作为一个整体,而其父亲即是这个整体紧邻的那个点。
也就是说每次遇到已经赋值的点时直接跳到它的下一个空点处,即它父亲,这样就不会超时了。。。。
代码:
1 #define maxn 3000100 2 char ans[maxn], tmp[maxn]; 3 int f[maxn]; 4 int n, len, k, c, maxcur = 0; 5 6 int get(int x) { return x == f[x]? x: f[x] = get(f[x]); } 7 void unite(int x, int y){ 8 int rx = get(x), ry = get(y); 9 if(rx == ry) return; 10 else f[rx] =ry; 11 } 12 13 int main(){ 14 memset(ans, 0, sizeof(ans)); 15 for(int i = 0; i < maxn; i++) ans[f[i] = i] = 'a'; 16 scanf("%d", &n); 17 while(n--){ 18 scanf("%s", tmp + 1); 19 len = strlen(tmp + 1); 20 scanf("%d", &k); 21 while(k--){ 22 scanf("%d", &c); 23 maxcur = max(maxcur, c + len - 1); 24 25 for(int i = c; i < c + len; i = get(i)){ 26 ans[i] = tmp[i - c + 1]; 27 unite(i, i + 1); 28 } 29 } 30 } 31 ans[maxcur + 1] = '