hdoj 5927 Auxiliary Set && hdoj 5929 Basic Data Structure

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenzhenyu123456/article/details/52745318

人菜就要少揽事,呵呵~~~ 忙了两天一夜,有什么用。

hdoj 5927 Auxiliary Set

WA RE 交替中度过,还是太SB,太相信那个’有根’一词了。
一、有根树,但是边是无向的;
二、在预处理DFS信息时,用邻接表存图。

题意:定义 u 是合法点
1、 u 是重要点
2、 u 是某两个不同重要点的最近公共祖先。
每次给定非重要点,问你一共有多少个合法点。

思路:显然只要 u 的两个或者多于两个子树里面至少存在一个重要点,那么 u 肯定也是重要点。
定义 yes[v]==true 时, v 的子树里面全是非重要点。
这样若 u 的儿子数目 son[u] 减去 son[u]i=1(yes[i]==true)>=2 说明 u 是合法的。
非重要点数目很少,而重要点的信息我们也不需要,这样可以根据父子关系重新建个图,跑搜索即可。

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 100;
const int MOD = 1e9 + 7;
struct Edge {
    int to, next;
};
Edge edge[MAXN * 2];
int head[MAXN], edgenum;
void addEdge(int u, int v) {
    Edge E = {v, head[u]};
    edge[edgenum] = E;
    head[u] = edgenum++;
}
void add(LL &x, LL y) {
    x += y;
    if(x >= MOD) x -= MOD;
}
vector<int> G[MAXN];
bool vis[MAXN];
int son[MAXN], pre[MAXN];
int ans;
void Init(int u, int fa) {
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(v == fa) continue;
        Init(v, u);
        son[u]++; pre[v] = u;
    }
}
bool DFS(int u) {
    // true all important
    // false not
    int cnt = 0;
    for(int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if(DFS(v)) {
            cnt++;
        }
    }
    if(son[u] - cnt >= 2) {
        ans++;
    }
    if(cnt == son[u]) return true;
    return false;
}
int x[MAXN];
int in[MAXN];
int main()
{
    int t, kcase = 1; scanf("%d", &t);
    while(t--) {
        int n, q; scanf("%d%d", &n, &q);
        for(int i = 1; i <= n; i++) {
            vis[i] = false; son[i] = 0;
            //G[i].clear();
            head[i] = -1;
        }
        edgenum = 0; pre[1] = -1;
        for(int i = 1; i <= n - 1; i++) {
            int u, v; scanf("%d%d", &u, &v);
            addEdge(u, v);
            addEdge(v, u);
            //G[u].push_back(v);
            //G[v].push_back(u);
        }
        Init(1, -1);
        //for(int i = 1; i <= n; i++) G[i].clear();
        printf("Case #%d:\n", kcase++);
        while(q--) {
            int m; scanf("%d", &m);
            ans = n - m;
            for(int i = 1; i <= m; i++) {
                scanf("%d", &x[i]);
                vis[x[i]] = true;
                G[x[i]].clear();
                in[x[i]] = 0;
            }
            for(int i = 1; i <= m; i++) {
                if(pre[x[i]] != -1 && vis[pre[x[i]]]) {
                    G[pre[x[i]]].push_back(x[i]);
                    in[x[i]]++;
                }
            }
            for(int i = 1; i <= m; i++) {
                if(in[x[i]] == 0) {
                    DFS(x[i]);
                }
                vis[x[i]] = false;
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

hdoj 5929 Basic Data Structure

题意:有若干个操作。
反转栈,元素进栈,出栈,查询 atopnandatop1nand...nanda1

发现元素 0 的特殊性,那么就用一个双端队列去维护,维护的信息是每个0前面连续1的个数。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int Queue[400000 + 10];
int main()
{
    int T, kcase = 1; scanf("%d", &T);
    while(T--) {
        int N; scanf("%d", &N);
        for(int i = 0; i <= 2 * N + 10; i++) Queue[i] = 0;
        bool flag = true;
        int L, R; L = R = N;
        int cnt = 0;
        printf("Case #%d:\n", kcase++);
        for(int i = 0; i < N; i++) {
            char op[10]; int v;
            scanf("%s", op);
            if(op[0] == 'P') {
                if(op[1] == 'U') {
                    scanf("%d", &v);
                    if(flag) {
                        if(v == 0) {
                            Queue[R++] = cnt + 1;
                            cnt = 0;
                        }
                        else {
                            cnt++;
                        }
                    }
                    else {
                        if(v == 0) {
                            Queue[--L] = 1;
                        }
                        else {
                            if(L != R) {
                                Queue[L]++;
                            }
                            else {
                                cnt++;
                            }
                        }
                    }
                }
                else {
                    if(flag) {
                        if(cnt == 0) {
                            cnt = Queue[R - 1] - 1;
                            Queue[R - 1] = 0; R--;
                        }
                        else {
                            cnt--;
                        }
                    }
                    else {
                        if(L != R) {
                            if(--Queue[L] == 0) {
                                L++;
                            }
                        }
                        else {
                            cnt--;
                        }
                    }
                }
            }
            else if(op[0] == 'Q') {
                if(L == R) {
                    if(cnt == 0) {
                        printf("Invalid.\n");
                    }
                    else {
                        if(cnt & 1) {
                            printf("1\n");
                        }
                        else {
                            printf("0\n");
                        }
                    }
                }
                else if(!flag) {
                    if(L == R - 1 && Queue[R - 1] == 1) { // 0
                        if(cnt & 1) {
                            printf("1\n");
                        }
                        else {
                            printf("0\n");
                        }
                    }
                    else { // 1
                        if(cnt & 1) {
                            printf("0\n");
                        }
                        else {
                            printf("1\n");
                        }
                    }
                }
                else {
                    if(L == R - 1 && cnt == 0) { // 0
                        if((Queue[L] - 1) & 1) {
                            printf("1\n");
                        }
                        else {
                            printf("0\n");
                        }
                    }
                    else { // 1
                        if((Queue[L] - 1) & 1) {
                            printf("0\n");
                        }
                        else {
                            printf("1\n");
                        }
                    }
                }
            }
            else {
                flag = !flag;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/chenzhenyu123456/article/details/52745318
今日推荐