正睿提高组2017模拟题四T3

明明三道都是水题,我却只有144。。。

这道题我们用两个vector来储存。

a[x]储存的是x这个位置放过的球的标号,和放进这个球时是第几次交换。

b[x]储存的是x这个球放过哪些位置,和放到那个位置是第几次交换。

所以对于每次询问我们只要先二分出第x个位置在第l次操作之前放的是几号球,然后再二分出这个球在第r次操作后放到了哪个位置,就是答案了。

是不是觉得很水,然而当时同学们都打得是分块,并且我还不会打。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxn 200009
using namespace std;
int n,m,q;
vector< pair<int,int> >a[maxn],b[maxn];
int main()
{
  scanf("%d%d%d",&n,&m,&q);
  for (int i=1;i<=n;i++)
  {
    pair<int,int>xx;
    xx.first=0;
    xx.second=i;
      a[i].push_back(xx);
      b[i].push_back(xx);
  }
  int x,y;
  for (int i=1;i<=m;i++)
  {
      scanf("%d%d",&x,&y);
      int w1=a[x][a[x].size()-1].second;
      int w2=a[y][a[y].size()-1].second;
      b[w1].push_back(make_pair(i,y));
      b[w2].push_back(make_pair(i,x));
      a[x].push_back(make_pair(i,w2));
      a[y].push_back(make_pair(i,w1));
  }
  for (int i=1;i<=q;i++)
  {
      int x,l,r;
    scanf("%d%d%d",&x,&l,&r);
    int lef=0,righ=a[x].size()-1;
    while (lef<righ)
    {
      int mid=(lef+righ+1)>>1;
      if (a[x][mid].first>=l) righ=mid-1;
      else lef=mid;
    }     
    int now=a[x][lef].second;
    lef=0;righ=b[now].size()-1;
    while (lef<righ)
    {
      int mid=(lef+righ+1)>>1;
      if (b[now][mid].first<=r) lef=mid;
      else righ=mid-1;    
    }
    printf("%d ",b[now][lef].second);
  }
  return 0;
}

原文地址:https://www.cnblogs.com/2014nhc/p/7544045.html