C.Swap

  • 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;
}
posted @ 2024-11-06 11:21  D06  阅读(17)  评论(0)    收藏  举报
//雪花飘落效果