답안 #248769

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
248769 2020-07-13T10:38:34 Z vanic Svjetlost (COI18_svjetlost) C++14
14 / 100
57 ms 12408 KB
#include <iostream>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <iomanip>

using namespace std;

typedef long long ll;
const int maxn=1e5+5, pot=(1<<17);

int n;
pair < int, int > tock[maxn];
pair < int, int > vektor[maxn];

int lij[maxn], des[maxn];

struct tournament{
	double t[pot*2];
	double prop[pot*2];
	void propagate(int x){
		t[x]+=prop[x];
		if(x<pot){
			prop[x*2]+=prop[x];
			prop[x*2+1]+=prop[x];
		}
		prop[x]=0;
	}
	void update(int x, double val){
		t[x]+=val;
		for(x/=2; x>0; x/=2){
			propagate(x*2);
			propagate(x*2+1);
			t[x]=max(t[x*2], t[x*2+1]);
		}
	}
	void update1(int L, int D, int x, int l, int d, double val){
		propagate(x);
		if(L>=l && D<=d){
//			cout << "updateam " << x << endl;
			update(x, val);
			if(x<pot){
				prop[x*2]+=val;
				prop[x*2+1]+=val;
			}
			return;
		}
		if((L+D)/2>=l){
			update1(L, (L+D)/2, x*2, l, d, val);
		}
		if((L+D)/2+1<=d){
			update1((L+D)/2+1, D, x*2+1, l, d, val);
		}
	}
	double query(int L, int D, int x, int l, int d){
		propagate(x);
		if(L>=l && D<=d){
			return t[x];
		}
		double lijeva=0, desna=0;
		if((L+D)/2>=l){
			lijeva=query(L, (L+D)/2, x*2, l, d);
		}
		if((L+D)/2+1<=d){
			desna=query((L+D)/2+1, D, x*2+1, l, d);
		}
		return max(lijeva, desna);
	}
	void cisti(int L, int D, int x, int l, int d){
		propagate(x);
		if(L>=l && D<=d){
			return;
		}
		if((L+D)/2>=l){
			cisti(L, (L+D)/2, x*2, l, d);
		}
		if((L+D)/2+1<=d){
			cisti((L+D)/2+1, D, x*2+1, l, d);
		}
	}
};

struct tournament1{
	double t[pot*2];
	void update(int x, double val){
		t[x]=val;
		for(x/=2; x>0; x/=2){
			t[x]=t[x*2]+t[x*2+1];
		}
	}
	double query(int L, int D, int x, int l, int d){
		if(L>=l && D<=d){
			return t[x];
		}
		double lijeva=0, desna=0;
		if((L+D)/2>=l){
			lijeva=query(L, (L+D)/2, x*2, l, d);
		}
		if((L+D)/2+1<=d){
			desna=query((L+D)/2+1, D, x*2+1, l, d);
		}
		return lijeva+desna;
	}
};


ll ccw(pair < ll, ll > a, pair < ll, ll > b, pair < ll, ll > c){
	return a.first*(b.second-c.second)+b.first*(c.second-a.second)+c.first*(a.second-b.second);
}

double dist(pair < double, double > a, pair < double, double > b){
	return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));
}


struct tournament2{
	pair < int, int > t[pot*2];
	pair < int, int > prop[pot*2];
	pair < int, int > prazno={1e9+1, 1e9+1};
	tournament2(){
		for(int i=0; i<pot*2; i++){
			prop[i]=prazno;
		}
	}
	void propagate(int x){
		if(prop[x]!=prazno){
			t[x]=prop[x];
			if(x<pot){
				prop[x*2]=prop[x];
				prop[x*2+1]=prop[x];
			}
			prop[x]=prazno;
		}
	}
	void update(int x, pair < int, int > val){
		t[x]=val;
		for(x/=2; x>0; x/=2){
			propagate(x*2+1);
			t[x]=t[x*2+1];
		}
	}
	void update1(int L, int D, int x, int l, int d, pair < int, int > val){
		propagate(x);
		if(L>=l && D<=d){
			update(x, val);
			if(x<pot){
				prop[x*2]=val;
				prop[x*2+1]=val;
			}
			return;
		}
		if((L+D)/2>=l){
			update1(L, (L+D)/2, x*2, l, d, val);
		}
		if((L+D)/2+1<=d){
			update1((L+D)/2+1, D, x*2+1, l, d, val);
		}
	}
	int query(int L, int D, int x, int l, int d, pair < int, int > val){
		propagate(x);
		int y;
		if(L>=l && D<=d){
			if(ccw({0, 0}, val, t[x])>0){
				return -1;
			}
			if(val==t[x]){
				return -1;
			}
			if(x>=pot){
				return x-pot;
			}
			if(ccw({0, 0}, val, t[x*2])>0 || t[x*2]==val){
				return query((L+D)/2+1, D, x*2+1, l, d, val);
			}
			else{
				return query(L, (L+D)/2, x*2, l, d, val);
			}
		}
		if((L+D)/2>=l){
			y=query(L, (L+D)/2, x*2, l, d, val);
			if(y!=-1){
				return y;
			}
		}
		if((L+D)/2+1<=d){
			return query((L+D)/2+1, D, x*2+1, l, d, val);
		}
		return -1;
	}
	
};

tournament T;
tournament1 T1;
tournament2 T2;


int binary(int pos){
	int lo=0, hi=n, mid;
	while(lo<hi){
		mid=(lo+hi)/2+1;
		if(ccw({0, 0}, vektor[pos], vektor[(pos+mid)%n])>0){
			lo=mid;
		}
		else{
			hi=mid-1;
		}
	}
	return lo;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	cout << fixed;
	cout << setprecision(6);
	int a, b;
	for(int i=0; i<n; i++){
		cin >> a >> b;
		tock[i]={a, b};
		lij[i]=(i+n-1)%n;
		des[i]=(i+1)%n;
	}
	for(int i=0; i<n; i++){
		if(i!=n-1){
			vektor[i]={tock[i+1].first-tock[i].first, tock[i+1].second-tock[i].second};
			T1.update(i+pot, dist(tock[i], tock[i+1]));
		}
		else{
			vektor[i]={tock[0].first-tock[i].first, tock[0].second-tock[i].second};
			T1.update(i+pot, dist(tock[i], tock[0]));
		}
		T2.update(i+pot, vektor[i]);
	}
	int pos=1;
	double val=dist({0, 0}, vektor[0]);
	for(int i=0; i<n; i++){
		while(ccw({0, 0}, vektor[i], vektor[pos])>0){
			val+=dist({0, 0}, vektor[pos]);
			pos=(pos+1)%n;
		}
//		cout << val << '\n';
		T.update(pot+i, val);
		val-=dist({0, 0}, vektor[i]);
	}
	cout << T.query(0, pot-1, 1, 0, n-1) << '\n';
	int q;
	cin >> q;
	int x;
	for(int i=0; i<q; i++){
		cin >> a;
		a--;
//		x=(binary(a)+a)%n;
		x=T2.query(0, pot-1, 1, a, n-1, vektor[a]);
		if(x==-1){
			x=T2.query(0, pot-1, 1, 0, a-1, vektor[a]);
		}
		if(ccw({0, 0}, vektor[a], vektor[x])==0){
			x=(x+1)%n;
		}
//		cout << a << " " << x << endl;
		if(x>a){
			T.update1(0, pot-1, 1, x, n-1, -dist({0, 0}, vektor[a]));
			T.update1(0, pot-1, 1, 0, a, -dist({0, 0}, vektor[a]));
		}
		else{
			T.update1(0, pot-1, 1, x, a, -dist({0, 0}, vektor[a]));
		}

/*		T.cisti(0, pot-1, 1, x, x);
		cout << T.t[x+pot] << endl;*/
		x=T2.query(0, pot-1, 1, lij[a], n-1, vektor[lij[a]]);
		if(x==-1){
			x=T2.query(0, pot-1, 1, 0, lij[a]-1, vektor[lij[a]]);
		}
//		x=(binary(lij[a])+lij[a])%n;
		if(ccw({0, 0}, vektor[lij[a]], vektor[x])==0){
			x=(x+1)%n;
		}
//		cout << lij[a] << " " << x << endl;
/*		cout << vektor[lij[a]].first << " " << vektor[lij[a]].second << '\n';
		cout << vektor[x].first << " " << vektor[x].second << '\n';*/
//		cout << "kraj\n";
		if(x>lij[a]){
			T.update1(0, pot-1, 1, x, n-1, -dist({0, 0}, vektor[lij[a]]));
			T.update1(0, pot-1, 1, 0, lij[a], -dist({0, 0}, vektor[lij[a]]));
		}
		else{
			T.update1(0, pot-1, 1, x, lij[a], -dist({0, 0}, vektor[lij[a]]));
		}
/*
		cout << dist({0, 0}, vektor[lij[a]]) << endl;
		T.cisti(0, pot-1, 1, x, x);
		cout << T.t[x+pot] << endl;
*/
		vektor[lij[a]]={tock[des[a]].first-tock[lij[a]].first, tock[des[a]].second-tock[lij[a]].second};
		if(lij[a]<a){
			T2.update1(0, pot-1, 1, lij[a], a, vektor[lij[a]]);
		}
		else{
			T2.update1(0, pot-1, 1, lij[a], n-1, vektor[lij[a]]);
			T2.update1(0, pot-1, 1, 0, a, vektor[lij[a]]);
		}
		T1.update(lij[a]+pot, dist(tock[des[a]], tock[lij[a]]));
		T1.update(a+pot, 0);
		T.cisti(0, pot-1, 1, lij[a], lij[a]);
		T.cisti(0, pot-1, 1, a, a);
		T.update(a+pot, -T.t[a+pot]);
		T.update(a+pot, -1e9);
		T.update(lij[a]+pot, -T.t[lij[a]+pot]);
		lij[des[a]]=lij[a];
		des[lij[a]]=des[a];
		x=T2.query(0, pot-1, 1, lij[a], n-1, vektor[lij[a]]);
//		cout << lij[a] << " " << x << endl;
		if(x==-1){
			x=T2.query(0, pot-1, 1, 0, lij[a]-1, vektor[lij[a]]);
		}
		x=(x+n-1)%n;
//		x=(binary(lij[a])+lij[a])%n;
//		cout << lij[a] << " " << x << endl;
//		cout << vektor[lij[a]].first << " " << vektor[lij[a]].second << '\n';
		if(x>lij[a]){
			T.update(lij[a]+pot, T1.query(0, pot-1, 1, lij[a], x));
/*			cout << "tu" << endl;
			cout << T1.query(0, pot-1, 1, lij[a], x) << '\n';*/
		}
		else{
			T.update(lij[a]+pot, T1.query(0, pot-1, 1, lij[a], n-1)+T1.query(0, pot-1, 1, 0, x));
/*			cout << "ovdje" << endl;
			cout << T1.query(0, pot-1, 1, lij[a], n-1)+T1.query(0, pot-1, 1, 0, x) << '\n';*/
		}
		if(ccw({0, 0}, vektor[lij[a]], vektor[(x+1)%n])==0){
			x=(x+1)%n;
		}
		x=(x+1)%n;
//		cout << T.query(0, pot-1, 1, 0, n-1) << '\n';
//		cout << lij[a] << " " << x << endl;
/*
		T.cisti(0, pot-1, 1, x, x);
		cout << T.t[x+pot] << endl;*/

		if(x>lij[a]){
			T.update1(0, pot-1, 1, x, n-1, dist({0, 0}, vektor[lij[a]]));
			if(lij[a]){
				T.update1(0, pot-1, 1, 0, lij[a]-1, dist({0, 0}, vektor[lij[a]]));
			}
		}
		else{
			T.update1(0, pot-1, 1, x, lij[a]-1, dist({0, 0}, vektor[lij[a]]));
		}
		cout << T.query(0, pot-1, 1, 0, n-1) << '\n';
	}
	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4608 KB 11 numbers
2 Incorrect 3 ms 4608 KB 21st numbers differ - expected: '35400.0045282776', found: '42398.9525920000', error = '0.1977103720'
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4608 KB 11 numbers
2 Incorrect 3 ms 4608 KB 21st numbers differ - expected: '35400.0045282776', found: '42398.9525920000', error = '0.1977103720'
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4608 KB found '32934.3604540000', expected '32934.3604541195', error '0.0000000000'
2 Correct 4 ms 4736 KB found '31571636.3365450017', expected '31571636.3365447633', error '0.0000000000'
3 Correct 9 ms 5632 KB found '31442617.6286690012', expected '31442617.6286691241', error '0.0000000000'
4 Correct 15 ms 6528 KB found '31424400.0534069985', expected '31424400.0534067489', error '0.0000000000'
5 Correct 54 ms 12408 KB found '3142086769.6889629364', expected '3142086769.6889681816', error '0.0000000000'
6 Correct 57 ms 12408 KB found '3142076120.8714442253', expected '3142076120.8714694977', error '0.0000000000'
# 결과 실행 시간 메모리 Grader output
1 Incorrect 14 ms 4864 KB 609th numbers differ - expected: '1043227215.3493254185', found: '1043891098.7507519722', error = '0.0006363747'
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4608 KB 11 numbers
2 Incorrect 3 ms 4608 KB 21st numbers differ - expected: '35400.0045282776', found: '42398.9525920000', error = '0.1977103720'
3 Halted 0 ms 0 KB -