这是一道神奇的我也不知道为啥标签有图论的题,题意就是给你数组a和数组b,让后让你找出两个下标i,和j,使得a[i]!=a[j],b[i]!=b[j] , 刚开始用图的思想去想了老半天,结果想了老半天之后换个思路直接就出来了:我们先让a[i],和b[i]绑到一块,然后安装a[i]为第一关键字排序,在进行去重,之后我们留下来的两个数组维护出来每个b[i]出现的和c[i], 然后再开始由前往后去遍历,每遍历到一个b[i],就让对应的c[b[i]] -- , 然后再找出除a[i]相同的在出去和b[i]相同的有多少个即可,由于我们排过序,并且去过重,这些操作都比较容易实现
另外用vector的erase和unique函数会超时这道题,手动写了个去重就过了,好像手动比函数要快(第一次见)
题目:
ac代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long int LL ;
typedef pair<int,int > PII ;
const int N = 2e5 + 10;
vector<PII> v;
int ne[N];
int num[N];
PII a[N];
int main()
{
int t;
cin >> t;
while(t--)
{
int A , B , n ;
cin >> A >> B >> n ;
a[0] = {1e9,1e9};
for(int i = 1; i <= n ; i ++)cin >> a[i].first;
for(int i = 1; i <= n ; i ++)cin >> a[i].second;
sort(a+1,a+1+n);
int cnt = 0;
for(int i = 1; i <= n ; i ++)
{
if(a[i] != a[i-1])a[++cnt] = a[i];
}
n = cnt;
ne[n+1] = n+1;
a[n+1] = {1e9,1e9};
for(int i = n ; i >= 1; i --)
{
if(a[i].first == a[i+1].first)ne[i] = ne[i + 1];
else ne[i] = i;
num[a[i].second] ++ ;
}
LL res = 0 ;
for(int i = 1; i <= n ; i ++)
{
int j = ne[i]+1;
num[a[i].second] -- ;
if(j <= n)
{
res += n - j + 1 - num[a[i].second];
}
// cout << i <<' '<<res <<' '<< j <<' '<<num[a[i].second] <<endl;
}
cout << res <<endl;
}
}