Submission #447843

#TimeUsernameProblemLanguageResultExecution timeMemory
447843koioi.org-koosaga육각형 영역 (APIO21_hexagon)C++17
60 / 100
75 ms24140 KiB
#include "hexagon.h"
#include <bits/stdc++.h>
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
using namespace std;
typedef long long lint;
typedef pair<int, int> pi;
const int MAXN = 300005;
const int dx[6] = {0, 1, 1, 0, -1, -1};
const int dy[6] = {1, 1, 0, -1, -1, 0};
const int mod = 1e9 + 7;

struct mint {
    int val;
    mint() { val = 0; }
    mint(const lint& v) {
        val = (-mod <= v && v < mod) ? v : v % mod;
        if (val < 0) val += mod;
    }

    friend ostream& operator<<(ostream& os, const mint& a) { return os << a.val; }
    friend bool operator==(const mint& a, const mint& b) { return a.val == b.val; }
    friend bool operator!=(const mint& a, const mint& b) { return !(a == b); }
    friend bool operator<(const mint& a, const mint& b) { return a.val < b.val; }

    mint operator-() const { return mint(-val); }
    mint& operator+=(const mint& m) { if ((val += m.val) >= mod) val -= mod; return *this; }
    mint& operator-=(const mint& m) { if ((val -= m.val) < 0) val += mod; return *this; }
    mint& operator*=(const mint& m) { val = (lint)val*m.val%mod; return *this; }
    friend mint ipow(mint a, lint p) {
        mint ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend mint inv(const mint& a) { assert(a.val); return ipow(a, mod - 2); }
    mint& operator/=(const mint& m) { return (*this) *= inv(m); }

    friend mint operator+(mint a, const mint& b) { return a += b; }
    friend mint operator-(mint a, const mint& b) { return a -= b; }
    friend mint operator*(mint a, const mint& b) { return a *= b; }
    friend mint operator/(mint a, const mint& b) { return a /= b; }
    operator int64_t() const {return val; }
};

lint ccw(pi a, pi b, pi c){
	int dx1 = b.first - a.first;
	int dy1 = b.second - a.second;
	int dx2 = c.first - a.first;
	int dy2 = c.second - a.second;
	return 1ll * dx1 * dy2 - 1ll * dy1 * dx2;
}

bool turn(vector<pi> &a){
	lint A = 0;
	for(int i = 2; i < sz(a); i++) A += ccw(a[0], a[i-1], a[i]);
	return A > 0;
}

struct node{
	int p, s, e;
	bool operator<(const node &n)const{
		return pi(p, s) < pi(n.p, n.s);
	}
};

vector<int> len[200005];
vector<node> vect;
vector<int> gph[MAXN];

mint solve(int x, int p, int d){
	mint ret = mint(d) * mint(vect[x].e - vect[x].s + 1);
	for(auto &i : gph[x]){
		if(i != p) ret += solve(i, x, d + 1);
	}
	return ret;
}


int solve(vector<pi> v){
	vect.clear();
	for(int i = 0; i < MAXN; i++){
		gph[i].clear();
	}
	int xmin = 1e9;
	if(!turn(v)) reverse(v.begin() + 1, v.end());
	for(auto &[x, y] : v){
		xmin = min(xmin, x);
	}
	int xmax = 0;
	for(auto &[x, y] : v){
		x -= xmin;
		xmax = max(xmax, x);
	}
	for(int i = 0; i < sz(v); i++){
		auto s = v[i], e = v[(i + 1) % sz(v)];
		auto p = v[(i + sz(v) - 1) % sz(v)];
		if(s.first == e.first){
			if(s.second < e.second){
				if(p.first < s.first) len[s.first].push_back(s.second);
			}
			else{
				if(p.first > s.first) len[s.first].push_back(s.second);
			}
			continue;
		}
		int delta = (e.second - s.second) / (e.first - s.first);
		if(s.first < e.first){
			if(p.first < s.first || (p.first == s.first && p.second > s.second)) len[s.first].push_back(s.second);
			if(p.first > s.first){
				len[s.first].push_back(s.second);
				len[s.first].push_back(s.second);
			}
			for(int j = s.first + 1; j < e.first; j++) len[j].push_back(s.second + delta * (j - s.first));
		}
		else if(s.first > e.first){
			if(p.first > s.first || (p.first == s.first && p.second < s.second)) len[s.first].push_back(s.second);
			if(p.first < s.first){
				len[s.first].push_back(s.second);
				len[s.first].push_back(s.second);
			}
			for(int j = s.first - 1; j > e.first; j--) len[j].push_back(s.second + delta * (j - s.first));
		}
	}
	for(int i = 0; i <= xmax; i++){
		assert(sz(len[i]) % 2 == 0);
		sort(all(len[i]));
		vector<int> nlen = {len[i][0]};
		for(int j = 1; j < sz(len[i]) / 2; j++){
			if(len[i][2*j-1] + 1 == len[i][2*j]) continue;
			nlen.push_back(len[i][2*j-1]);
			nlen.push_back(len[i][2*j]);
		}
		nlen.push_back(len[i].back());
		len[i].clear();
		for(int j = 0; j < sz(nlen) / 2; j++){
			vect.push_back({i, nlen[2*j], nlen[2*j+1]});
		}
	}
		auto insec = [&](int j, int k){
			return max(vect[j].s, vect[k].s) <= min(vect[j].e + 1, vect[k].e);
		};
	for(int i = 0; i < xmax; i++){
		int p = lower_bound(all(vect), (node){i, -int(1e9), -1}) - vect.begin();
		int q = lower_bound(all(vect), (node){i+1, -int(1e9), -1}) - vect.begin();
		int r = lower_bound(all(vect), (node){i+2, -int(1e9), -1}) - vect.begin();
		int k = q;
		for(int j = p; j < q; j++){
			while(k < r && vect[k].e < vect[j].s) k++;
			if(insec(j, k)){
				while(k < r && insec(j, k)){
					gph[j].push_back(k);
					gph[k].push_back(j);
					k++;
				}
				k--;
			}
		}
	}
//	cout << "sz(vect) = " << sz(vect) << endl;
	for(int i = 0; i < sz(vect); i++){
//		printf("vect[%d] =(%d %d %d)\n", i, vect[i].p, vect[i].s, vect[i].e);
	}
	mint ans = 0;
	for(int i = 0; i < sz(vect); i++){
		if(vect[i].p == -xmin && vect[i].s <= 0 && 0 <= vect[i].e){
//			cout << "init " << i << endl;
			return solve(i, -1, 0);
		}
	}
	assert(0);
}

int draw_territory(int N, int _A, int _B,
		std::vector<int> D, std::vector<int> L) {
	for(auto &i : D) i--;
	vector<pi> a(N);
	for(int i = 1; i < N; i++){
		a[i].first = a[i-1].first + dx[D[i-1]] * L[i-1];
		a[i].second = a[i-1].second + dy[D[i-1]] * L[i-1];
	}
	lint A = 0;
	lint B = accumulate(all(L), 0ll);
	for(int i = 2; i < N; i++) A += ccw(a[0], a[i-1], a[i]);
	A = abs(A);
	lint I = (A - B + 2) / 2;
	mint sumA = mint(I + B) * mint(_A);
	mint sumB = 0;
	for(int _ = 0; _ < 3; _++){
		if(_B == 0) continue;
		vector<pi> a(N);
		for(int i = 1; i < N; i++){
			a[i].first = a[i-1].first + dx[D[i-1]] * L[i-1];
			a[i].second = a[i-1].second + dy[D[i-1]] * L[i-1];
		}
		sumB += solve(a);
		for(auto &j : D) j = (j + 1) % 6;
	}
	return sumA + mint(_B) * sumB / mint(2);
}

Compilation message (stderr)

hexagon.cpp: In function 'int solve(std::vector<std::pair<int, int> >)':
hexagon.cpp:162:7: warning: variable 'ans' set but not used [-Wunused-but-set-variable]
  162 |  mint ans = 0;
      |       ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...