蒟蒻代码,大体思路是把三元组看做一个2000进制的数字,枚举每个三元组把他当做(a,b,c),然后找所有(b,c)开头的就可以找到d。
我这里做了一个排序,然后提前处理了第一个(b,c)的位置,就不需要再次枚举。但是不知道怎么算时间复杂度,感觉如果特殊构造的数据应该会被hack掉呢?
求解平均时间复杂度,求大佬hack
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define N 222005
#define int long long
using namespace std;
unordered_map <int, bool> s;
unordered_map <int, int> pos;
struct node
{
int a;
int b;
int c;
int beg;
}arr[50005];
bool cmp( node s1, node s2 )
{
if ( s1.a == s2.a )
{
if ( s1.b == s2.b )
{
return s1.c < s2.c;
}
return s1.b < s2.b;
}
return s1.a < s2.a;
}
template <typename T>
void read ( T &x )
{
x = 0;
bool f = 0;
char c = getchar();
for( ; !isdigit(c); c=getchar() ) f=c=='0';
for( ; isdigit(c); c=getchar()) x=x*10+c-'0';
if( f ) x = -x;
}
void read( int &x ) {
x=0;
bool f=0;
char c=getchar();
for(;!isdigit(c);c=getchar()) f=c=='0';
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
if(f) x=-x;
}
signed main()
{
int n = 0, m = 0;
read( n ), read( m );
for ( int i = 1; i <= m; i ++ )
{
int a = 0, b = 0, c = 0;
read( a ), read( b ), read( c );
arr[i].a = a, arr[i].b = b, arr[i].c = c, arr[i].beg = a * 2000 + b;
int d = a * 4000000 + b * 2000 + c;
s[d] = 1;
}
sort( arr+1, arr+1+m, cmp );
for ( int i = 1; i <= m; i ++ )
{
if ( arr[i].beg != arr[i-1].beg )
{
pos[arr[i].beg] = i;
}
}
long long ans = 0;
for ( int i = 1; i <= m; i ++ )
{
int las = arr[i].b * 2000 + arr[i].c;
for ( int j = pos[las]; ( arr[j].beg == las ) && ( j <= m ); j ++ )
{
if ( arr[i].c >= arr[j].c )
{
continue;
}
int sec = arr[i].a * 4000000 + arr[i].b * 2000 + arr[j].c;
int thd = arr[i].a * 4000000 + arr[i].c * 2000 + arr[j].c;
if( s[sec] == 1 && s[thd] == 1 )
{
ans ++;
}
}
}
cout << ans << "\n";
return 0;
}
/*
2 4 5 6
2 4 5 9
9 11
2 4 5
2 5 6
4 5 6
2 4 6
1 3 5
1 3 6
3 5 6
1 5 6
4 6 9
5 6 9
4 5 9
*/