Submission #349551

# Submission time Handle Problem Language Result Execution time Memory
349551 2021-01-17T19:24:23 Z CaroLinda Printed Circuit Board (CEOI12_circuit) C++14
80 / 100
100 ms 37712 KB
#include <bits/stdc++.h>

#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops") 
#define sz(x) (int)(x.size())
#define debug printf
#define lp(i,a,b) for(int i = a ; i < b; i++)
#define pb push_back
#define ff first
#define ss second
#define mk make_pair
#define pii pair<int,int>
#define ll long long 
#define all(x) x.begin(),x.end()
 
const int MAX = 2e5+10 ;
 
using namespace std ;

char c ;
void readInt(int &num)
{
	num = 0 ;
	for(c = getchar() ; (c > 47 && c <58 ) ; c = getchar() )
		num = num*10 + c - 48 ;
}

void readLong(ll &num ) 
{
	num = 0 ;
	for(c = getchar() ; (c> 47 && c < 58 ) ; c = getchar() )
		num = num*10 + c - 48 ;
}
 
int N ;
int myId[MAX] ;
ll num[MAX], den[MAX] ;
 
struct Point
{
 
    ll x , y ;
 
    Point(ll x=0, ll y=0):x(x), y(y) {}
    
    bool operator == ( Point other ) const { return x == other.x && y == other.y ; }
    bool operator != (Point other ) const { return x != other.x || y != other.y ; }
    Point operator - (Point other) const { return Point(x-other.x, y-other.y) ; } 
    ll operator % (Point other) const { return x*other.y - y*other.x ; }
    ll operator *(Point other) const { return x*other.x + y*other.y ; }
    void read() { scanf("%lld %lld", &x, &y) ; }
} ;
 
struct Line
{
	Point p1, p2 ; 
	Line( Point p1 = Point(0,0) , Point p2 = Point(0,0) ) : p1(p1) , p2(p2) {} 
}  ;
 
bool isLess(ll num1, ll den1, ll num2, ll den2 )
{
	//It doesn't happen that den < 0, because x is always positive 
 
   if(num1 <= 1000000000 && den1 <= 1000000000 && num2 <= 1000000000 && den2 <= 1000000000 )
   	return num1*den2 < num2*den1 ;

	ll q1 = num1/den1 ;
	ll q2 = num2/den2 ;
	ll r1 = num1%den1 ;
	ll r2 = num2%den2 ;
 
	if( q1 != q2 ) return q1 < q2 ;
	if( r1 == 0 || r2 == 0 ) return r1 == 0 && r2 > 0 ;
 
	return isLess(den2, r2, den1, r1 ) ;
}
 
ll getNum( Line t, int id )
{
	return den[id] * ( t.p1.y*t.p2.x - t.p1.x*t.p2.y ) ;
}
 
ll getDen(Line t, int id )
{
	return den[id] * ( t.p1.y - t.p2.y ) - num[id] * (t.p1.x-t.p2.x ) ;
}
 
struct Seg
{
	Line tree[MAX*4] ;
	
	int m(int l, int r ) { return (l+r)>>1 ; }
 
	void addLine(int pos, int l, int r, int beg, int en, Line t )
	{
 
		if( l > en || r < beg ) return ;
		if( l >= beg && r <= en )
		{
			if( tree[pos].p1 == Point(0,0) ) return (void)(tree[pos] = t ) ; 
 
			//check if tree[pos] is less than t
			 
			for(auto e : {l , r } ) 
			{
				ll num1 = getNum(tree[pos], e) ;
				ll den1 = getDen(tree[pos], e ) ;
				ll num2 = getNum(t, e ) ;
				ll den2 = getDen(t, e ) ;
				
				if(den1 < 0 ) num1 = -num1 , den1 = -den1 ;
				if( den2 < 0 ) num2 = -num2, den2 = -den2 ;
 
				if( tree[pos].p1.x == tree[pos].p2.x ) num1 = tree[pos].p1.x, den1 = 1LL ;
				if(t.p1.x == t.p2.x ) num2 = t.p1.x , den2 = 1LL ;
 
				if(isLess(num1, den1, num2, den2 ) ) return ;
 
			}
			tree[pos] = t ;
  
			return ; 
		}
 
		addLine(pos<<1 , l , m(l,r) , beg, en, t ) ;
		addLine(pos<<1|1, m(l,r)+1, r, beg, en, t ) ;
 
	}
 
	bool qry(int pos, int l, int r, int x, Point p )
	{
 
		ll val1 = (tree[pos].p2 - tree[pos].p1)%(p-tree[pos].p1) ;
		ll val2 = (tree[pos].p2-tree[pos].p1)%(Point(0,0)-tree[pos].p1 ) ;
 
		if( tree[pos].p1 != p && tree[pos].p2 != p && tree[pos].p1 != Point(0,0) && (val1 < 0 ) != (val2 < 0)  )
			return false ;
 
		if( l == r ) return true ;
 
		if( x <= m(l,r) ) return qry(pos<<1 , l , m(l,r), x, p ) ;
		return qry(pos<<1|1, m(l,r)+1, r, x, p ) ;
 
	}
 
} seg ;
 
int main()
{
 
	readInt(N) ;
 
	vector<Point> p(N) ;
	vector< pair<Point, int> > sorted ;
 
	for(int i = 0 ; i < N ; i++ ) 
	{
		readLong(p[i].x) ;
		readLong(p[i].y) ;
		sorted.push_back( make_pair(p[i], i ) ) ;
	}
 
 	sort(all(sorted), [&]( pair<Point,int> a, pair<Point,int> b ) 
	{
		if( a.first%b.first == 0 ) return (b.first-a.first)*(Point(0,0)-a.first ) < 0 ;
		return a.first%b.first > 0 ;	
	} ) ; 
 
	int j = -1 ;
	for(int i = 0 ; i < N ; i++ ) 
	{
	   if(!i || sorted[i-1].first%sorted[i].first != 0 ) j++ ;
	   		
		myId[ sorted[i].second ] = j ;
 
		num[j] = sorted[i].first.y ;
		den[j] = sorted[i].first.x ;
	}
 
	//for(int i= 0 ; i < N ; i++ ) printf("%lld %lld\n", den[i], num[i] ) ;
 
	for(int i = 0 , nxt = 1 ; i < N ; i++, nxt++ )
	{
		if(nxt ==  N ) nxt = 0 ;
 
		int l = myId[i] , r = myId[nxt] ;
 
		if( l > r ) swap(l,r) ;
 
		if(l != r ) 
			seg.addLine(1, 0 , j, l,r, Line( p[i], p[nxt] ) ) ;  
	} 
 
	//seg.print(1,0,N-1) ;
 
	//Don't forget to check if there is someone in the same polar angle that mine (because, if there is, it fucks everything up )
 
	vector<int> ans ;
	for(int i=0 ; i < N ; i++ )
	{
		if(i && sorted[i-1].first%sorted[i].first == 0 ) continue ;
		if(seg.qry(1,0,j, myId[ sorted[i].second ] , sorted[i].first )) ans.push_back(sorted[i].second ) ;
	}
 
	sort(all(ans) ) ;
 
	printf("%d\n", sz(ans ) ) ;
	for(auto e : ans ) printf("%d ", e+1 ) ;
	printf("\n") ;
 
 
}

Compilation message

circuit.cpp:4: warning: ignoring #pragma GCC optimization [-Wunknown-pragmas]
    4 | #pragma GCC optimization ("O3")
      | 
circuit.cpp:5: warning: ignoring #pragma GCC optimization [-Wunknown-pragmas]
    5 | #pragma GCC optimization ("unroll-loops")
      |
# Verdict Execution time Memory Grader output
1 Correct 18 ms 25452 KB Output is correct
2 Correct 19 ms 25452 KB Output is correct
3 Correct 20 ms 25708 KB Output is correct
4 Correct 21 ms 25708 KB Output is correct
5 Correct 28 ms 26216 KB Output is correct
6 Correct 28 ms 26216 KB Output is correct
7 Correct 40 ms 27108 KB Output is correct
8 Correct 26 ms 26032 KB Output is correct
9 Correct 25 ms 26088 KB Output is correct
10 Correct 28 ms 26216 KB Output is correct
11 Correct 30 ms 26344 KB Output is correct
12 Correct 30 ms 26856 KB Output is correct
13 Correct 52 ms 27620 KB Output is correct
14 Correct 43 ms 28256 KB Output is correct
15 Correct 49 ms 28768 KB Output is correct
16 Correct 82 ms 31964 KB Output is correct
17 Execution timed out 154 ms 31708 KB Time limit exceeded
18 Execution timed out 149 ms 37584 KB Time limit exceeded
19 Execution timed out 150 ms 37712 KB Time limit exceeded
20 Execution timed out 330 ms 37584 KB Time limit exceeded