AT_abc395_d [ABC395D] Pigeon Swap

D - Pigeon Swap

题意

n个鸽子和笼子 编号1-n 每个鸽子在编号和自己一样的笼子里 

三种操作

  • 1 给定整数 a,b(1≤a≤N,1≤b≤N)将鸽子 a 从当前所在的巢中取出,放入巢 b。
  • 2 给定整数 a,b(1≤a<b≤N)将巢 a 中所有鸽子移动到巢 b,同时将巢 b 中所有鸽子移动到巢 a。这两个移动操作是同时进行的。
  • 3 给定整数 a(1≤a≤N) 输出鸽子 a 当前所在的巢的编号。

数据范围

  • 1≤N≤1e6
  • 1≤Q≤3e5

思路

数据范围很大 每次查询都要在o(1)完成

间接映射 有点巧妙 从洛谷的题解上学的

开三个数组 f[N],id[N],st[N]

维护一个数轴 数轴坐标id[a] 存储a号笼子对应的数轴坐标 通过笼子编号访问坐标   a为笼子编号

f[id[a]]存储数轴坐标上对应的笼子的编号

操作二时  交换a,b两个笼子 只需要交换id[a],id[b]上的笼子 之后再交换a,b对应的坐标

也就是

swap(f[id[a]],f[id[b]]);
swap(id[a],id[b]);

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define pii pair<int,int>
#define ar2 array<int,2>
#define ar3 array<int,3>
#define ar4 array<int,4>
#define endl '\n'
void cmax(int &a,int b){a=max(a,b);}
void cmin(int &a,int b){a=min(a,b);}
const int N=1e6+10,MOD=1e9+7,INF=0x3f3f3f3f,LINF=LLONG_MAX;
int id[N],f[N],st[N];


void solve() {
    int n,q;cin>>n>>q;
    for(int i=1;i<=n;i++){
        id[i]=i,f[i]=i,st[i]=i;
    }

    while(q--){
        int op,a,b;cin>>op;
        if(op==3){
            cin>>a;
            cout<<f[st[a]]<<endl;
            continue;
        }
        cin>>a>>b;
        if(op==1){
            st[a]=id[b];
        }else if(op==2){
            swap(f[id[a]],f[id[b]]);
            swap(id[a],id[b]);
        }
    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int t=1;
    // cin>>t;
    while (t--) solve();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值