CUC-SummerTraining-30 2018 浙江省赛 Mergeable Stack


题目链接:https://vjudge.net/contest/252597#problem/C

1.超内存了,如何处理


#include<stdio.h>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
typedef long long LL;
const int maxn = 300005;
stack<LL> nstack[maxn];
stack<LL> ss;
LL n, q,v,s;
int t,op;
void init()
{
    for (LL i = 0; i <= n; i++)
        while (!nstack[i].empty()) 
            nstack[i].pop();
}
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        init();
        scanf("%lld%lld", &n, &q);
        while (q--)
        {
            scanf("%d", &op);
            if (op == 1)
            {
                scanf("%lld%lld", &s, &v);
                nstack[s].push(v);
            }
            else if (op == 2)
            {
                scanf("%lld", &s);
                if (nstack[s].size())
                {
                    LL tmp = nstack[s].top();
                    nstack[s].pop();
                    printf("%lld\n", tmp);
                }
                else puts("EMPTY");
            }
            else
            {
                while (!ss.empty())ss.pop();
                scanf("%lld%lld", &s, &v);
                while(!nstack[v].empty())
                {
                    ss.push(nstack[v].top());
                    nstack[v].pop();
                }
                while (!ss.empty())
                {
                    nstack[s].push(ss.top());
                    ss.pop();
                }
            }
        }
    }
    return 0;
}

然后实在没办法优化内存,垂死挣扎改一些LL改成int,虽然我知道肯定不行,但是还是想交一发,果然还是mle(但我知道了int是可以存10^5)
难道不能用stl自带的栈来实现?
然后我去看了看底层的实现
这里写图片描述
emmm我把原来的代码所有的改成int(int也可以包括10^9啊啊啊),报了一个从未出现的错误:段错误
网上大神说是内存超了或者是编译器的问题?

#include<string.h>
#include<stdio.h>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
const int maxn = 1000005;
stack<int> nstack[maxn];
stack<int> ss;
int v, n, q, s;
int t, op;
void init()
{
    for (int i = 0; i <= n; i++)
        while (!nstack[i].empty()) nstack[i].pop();
}
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        init();
        scanf("%d%d", &n, &q);
        while (q--)
        {
            scanf("%d", &op);
            if (op == 1)
            {
                scanf("%d%d", &s, &v);
                nstack[s].push(v);
            }
            else if (op == 2)
            {
                scanf("%d", &s);
                if (nstack[s].size())
                {
                    printf("%d\n", nstack[s].top());
                    nstack[s].pop();
                }
                else puts("EMPTY");
            }
            else
            {
                while (!ss.empty())ss.pop();
                scanf("%d%d", &s, &v);
                while (!nstack[v].empty())
                {
                    ss.push(nstack[v].top());
                    nstack[v].pop();
                }
                while (!ss.empty())
                {
                    nstack[s].push(ss.top());
                    ss.pop();
                }
            }
        }
    }
    return 0;
}

我试了vector,仍旧mle

#include<stdio.h>
#include<string>
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 1000005;
vector<int> nstack[maxn];
int n, q, s,v;
int t, op;
void init()
{
    for (int i = 0; i <= n; i++)
        nstack[i].clear();
}
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        init();
        scanf("%d%d", &n, &q);
        while (q--)
        {
            scanf("%d", &op);
            if (op == 1)
            {
                scanf("%d%d", &s, &v);
                nstack[s].push_back(v);
            }
            else if (op == 2)
            {
                scanf("%d", &s);
                if (nstack[s].size())
                {
                    printf("%d\n", nstack[s][nstack[s].size() - 1]);
                    nstack[s].pop_back();
                }
                else puts("EMPTY");
            }
            else
            {
                scanf("%d%d", &s, &v);
                nstack[s].insert(nstack[s].end(),nstack[v].begin(), nstack[v].end());
                nstack[v].clear();
            }
        }
    }
    return 0;
}

那我改改list吧,过了
(有个神奇的函数叫splice)

#include<stdio.h>
#include<string>
#include<iostream>
#include<list>
using namespace std;
const int maxn = 1000005;
list<int> nstack[maxn];
int v, n, q, s;
int t, op;
void init()
{
    for (int i = 0; i <= n; i++)
        nstack[i].clear();
}
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        init();
        scanf("%d%d", &n, &q);
        while (q--)
        {
            scanf("%d", &op);
            if (op == 1)
            {
                scanf("%d%d", &s, &v);
                nstack[s].push_back(v);
            }
            else if (op == 2)
            {
                scanf("%d", &s);
                if (!nstack[s].empty())
                {
                    printf("%d\n", nstack[s].back());
                    nstack[s].pop_back();
                }
                else puts("EMPTY");
            }
            else
            {
                scanf("%d%d", &s, &v);
                nstack[s].splice(nstack[s].end(), nstack[v]);
                //我试了试不用内置函数会超时
                //原因是:用链表的内置函数
                //直接可以把一个链表的尾连接另一个链表的头,
                //而如果一个个结点弄的话肯定会超时,
                //同理两个stack进行拷贝时无内置函数应该也会超时,vector也是
                //list在进行插入删除有很多优势见https://www.cnblogs.com/shijingjing07/p/5587719.html
                /*while (!nstack[v].empty())
                {
                    nstack[s].push_back(nstack[v].front());
                    nstack[v].pop_front();
                }*/
            }
        }
    }
    return 0;
}

来自大神们的解释
为什么不能用stack
这里写图片描述
这里写图片描述

对了忘了补充大牛们用数组做的方法了:把所有数字都存在一个数组a中,然后用三个数组top,bottom,next分别记录栈顶,栈底和栈顶下一个数字在数组a下标的数字
这里写图片描述

猜你喜欢

转载自blog.csdn.net/sinat_42424364/article/details/82492430