CodeForces 828C String Reconstruction(并查集思想)

题意:给你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;
}

原文地址:https://www.cnblogs.com/KirinSB/p/9517004.html

时间: 2024-10-09 05:22:42

CodeForces 828C String Reconstruction(并查集思想)的相关文章

Codeforces 828C String Reconstruction【并查集巧妙运用】

LINK 题目大意 给你n个串和在原串中的出现位置,问原串 思路 直接跑肯定是GG 考虑怎么优化 因为保证有解,所以考虑过的点我们就不再考虑 用并查集维护当前每个点之后最早的没有被更新过的点 然后就做完了,很巧妙对吧 c++//Author: dream_maker #include<bits/stdc++.h> using namespace std; //---------------------------------------------- //typename typedef lo

DFS+并查集思想求被围绕的区域

class Solution { private int[][] dir= {{0,-1},{-1,0},{0,1},{1,0}}; private boolean[][] used; public boolean isMove(char[][] board,int x,int y) { if(x>=0&&x<board.length&&y>=0&&y<board[0].length) return true; return fals

codeforces 468B two set(并查集)

codeforces 468B two set(并查集)n+1 表示 B 组 n+2 表示 A 组 按照 这题的做法 应该是 如果 满足 num[ i ] a-num[ i ] 则他们同一组 但不一定 就一定是 都是 A 组 也可能都是 B 组 然而如果不满足这个条件的话,就直接加入 B组 然后如果满足 num[ i ] b-num[ i ] 则加入同一组 然后不满足就 加入 A 组 1 #include <bits/stdc++.h> 2 using namespace std ; 3 4

Codeforces 278C Learning Languages(并查集) 求连通块

Codeforces 278C Learning Languages(并查集) 求连通块 为什么最后还要getfather 一遍 比如 x 是 y 的父亲 然后你 Union(x,z) 然后 z 变成了 x 父亲 然后 y 的祖先就是错的了 题解 求一个无向图中有几个连通块 sum 特判 一下 如果 每一个人的语言都为 0 则答案为 sum 其他 答案则为 sum - 1 1 #include <bits/stdc++.h> 2 using namespace std ; 3 4 const

Codeforces 292D Connected Components (并查集)

Codeforces 292D Connected Components (并查集) 题意 给出一张无向图,每次询问删去第Li--Ri 条边 求此时有多少个连通块 题解 求出一个前缀 Li 表示 加入前 i 条边时图的连通状况 以及一个后缀 Ri 表示 加入后 i 条边时图的连通状况 对于每个询问 删除 s--t 条边 只要将 L s-1 和 R t+1 合并 一下 就行了 合并 其实 就是讲 s-1 和 t+1 对应的 f[ i ] Union 一下就行了 为什么 这就相当于把前缀 i 和 后

Codeforces 650C Table Compression (并查集)

题意:M×N的矩阵 让你保持每行每列的大小对应关系不变,将矩阵重写,重写后的最大值最小. 思路:离散化思想+并查集,详见代码 好题! 1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstdlib> 7 #include <bits/stdc

Codeforces Gym 100463E Spies 并查集

Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Description In the aftermath of Canada’s annexation of Pittsburgh tensions have been pretty high between Canada and the US. You have personally been hired

CodeForces 731C C - Socks 并查集

Description Arseniy is already grown-up and independent. His mother decided to leave him alone for m days and left on a vacation. She have prepared a lot of food, left some money and washed all Arseniy's clothes. Ten minutes before her leave she real

CodeForces 722C Destroying Array (并查集)

题意:给定 n 个数,然后每次破坏一个位置的数,那么剩下的连通块的和最大是多少. 析:用并查集来做,从后往前推,一开始什么也没有,如果破坏一个,那么我们就加上一个,然后判断它左右两侧是不是存在,如果存在,那么就合并起来, 然后不断最大值,因为这个最大值肯定是不递减,所以我们一直更新就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <s