SWERC 2019-2020 Problem D

题意

给一个超长的序列,以及 1 e 4 1e4 1e4个操作。
当然给了两个操作序列。
比较最后得到的结果是否相同,都操作失败也视为相同

题解

每个元素都是一个pair<int,int>,当然里面可能有嵌套。
我们可以对其进行哈希,或者说记录令pair<int,int>=x,那么对于pair<pair<int,int>,int>=pair<x,y>
这样就能保证不会变复杂了,哈希的时候两个操作序列用一个哈希(用map即可)。

并且最多1e4个操作,所以我们大气一点直接5e4,因为可以发现每次最多用到两个,所以其实2e4就够了。

每次都是拿出前两个,然后放回一个或两个。比较容易用双端队列deque实现。
每次出现pair合并的时候,重新哈希就行了。

#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

typedef long long ll;
const int maxn = 2e6+2000;
const ll mod = 1e9+7;

int now=0;
map<pair<int,int>,int>mp;
pair<int,int>G[maxn];
string str;

int A[maxn],B[maxn],n=5e4;
vector<int>vec[2];


int slove(int index){
    deque<int>dq;
    for(int i=1;i<=5e4;i++)dq.push_back(i);
    for(int i=0;i<str.size();i++){
        int t1=dq.front();dq.pop_front();
        int t2=dq.front();dq.pop_front();//提出前两个
        if(str[i]=='C')dq.push_front(t2),dq.push_front(t1),dq.push_front(t1);//a-X -> a-a-X
        if(str[i]=='D')dq.push_front(t2);//a-X -> X
        if(str[i]=='L'){
            auto it=G[t1];
            if(it.second==-1)return false;
            dq.push_front(t2);
            dq.push_front(it.first);
        }
        if(str[i]=='P'){
            int id;
            if(mp.count(make_pair(t1,t2)))id=mp[make_pair(t1,t2)];
            else id=mp[make_pair(t1,t2)]=++now,G[now]=make_pair(t1,t2);
            dq.push_front(id);
        }
        if(str[i]=='R'){
            auto it=G[t1];
            if(it.second==-1)return false;
            dq.push_front(t2);
            dq.push_front(it.second);
        }
        if(str[i]=='S'){
            dq.push_front(t1);
            dq.push_front(t2);
        }
        if(str[i]=='U'){
            auto it=G[t1];
            if(it.second==-1)return false;
            dq.push_front(t2);
            dq.push_front(it.second);
            dq.push_front(it.first);
        }
    }
    while(!dq.empty()){
        vec[index].push_back(dq.front());
        dq.pop_front();
    }
    return true;
}

int main(){
    for(int i=1;i<=5e4;i++){
        mp[make_pair(i,-1)]=++now;
        G[now]=make_pair(i,-1);
    }
    cin>>str;
    int c1=slove(0);
    cin>>str;
    int c2=slove(1);
    if(c1==true){
        if(c1==c2&&vec[0]==vec[1])puts("True");
        else puts("False");
    }
    else{
        if(c1==c2)puts("True");
        else puts("False");
    }
}

``
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值