- iota:用从起始值开始连续递增的值填充一个范围,命名来源于希腊字母。如:
iota(p+1,p+n+1,1);
- vector:emplace_back:在容器末尾原位构造元素。如:
vector<pair<int,int> >vr[1000005];
vr[r].emplace_back(i,k);
- 类似的,queue的push也存在对应的emplace函数
- 结构化绑定声明(C++17):[标识符列表] = 表达式。如果需要引用,需要把&号放在中括号前。如:
auto [id,v]=vr[i]
- 基于范围的 for 循环,即:for (range_declaration : range_expression) loop_statement。如:
auto [id,v]:vr[i]
- 奇妙的是,通过扫描,这道题可以在线性的时间内解决
- 怎么做呢?注意到“交换元素”是可逆的信息,我们把每个询问的l和r挂到区间上,离线倒序处理,通过差分,就能求出每个询问的答案
#include <bits/stdc++.h>
using namespace std;
int a[1000005],b[1000005];
int p[1000005],inv[1000005];
int ans[1000005];
vector<int>vl[1000005];
vector<pair<int,int> >vr[1000005];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m,q;
cin>>n>>m>>q;
iota(p+1,p+n+1,1);
for(int i=1;i<=m;i++)
{
cin>>a[i]>>b[i];
swap(p[a[i]],p[b[i]]);
}
for(int i=1;i<=n;i++)
{
inv[p[i]]=i;
}
for(int i=1;i<=q;i++)
{
int l,r,k;
cin>>l>>r>>k;
vl[l].push_back(i);
vr[r].emplace_back(i,k);
}
for(int i=m;i>=1;i--)
{
for(auto [id,k]:vr[i])
{
ans[id]=p[k];
}
swap(p[a[i]],p[b[i]]);
swap(inv[p[a[i]]],inv[p[b[i]]]);
for(auto j:vl[i])
{
ans[j]=inv[ans[j]];
}
}
for(int i=1;i<=q;i++)
{
cout<<ans[i]<<"\n";
}
return 0;
}