Submission #1326427

#TimeUsernameProblemLanguageResultExecution timeMemory
1326427boclobanchatMixture (BOI20_mixture)C++20
100 / 100
445 ms59008 KiB
#include<bits/stdc++.h>
using namespace std;
const __int128 base=183667183667;
struct ftype
{
	__int128 a,b;
	ftype& operator+= (const ftype& p)
	{
		a=a*p.b+b*p.a,b*=p.b;
		return *this;
	}
	ftype& operator-= (const ftype& p)
	{
		a=a*p.b-b*p.a,b*=p.b;
		return *this;
	}
	ftype& operator*= (const ftype& p)
	{
		a*=p.a,b*=p.b;
		return *this;
	}
};
ftype operator+ (const ftype& x,const ftype& y)
{
	return (ftype){x.a*y.b+x.b*y.a,x.b*y.b};
}
ftype operator- (const ftype& x,const ftype& y)
{
	return (ftype){x.a*y.b-x.b*y.a,x.b*y.b};
}
ftype operator* (const ftype& x,const ftype& y)
{
	return (ftype){x.a*y.a,x.b*y.b};
}
ftype operator/ (const ftype& x,const ftype& y)
{
	return (ftype){x.a*y.b,x.b*y.a};
}
struct point
{
	ftype x,y;
	point& operator+= (const point& a)
	{
		x+=a.x,y+=a.y;
		return *this;
	}
	point& operator-= (const point& a)
	{
		x-=a.x,y-=a.y;
		return *this;
	}
	point& operator*= (ftype a)
	{
		x*=a,y*=a;
		return *this;
	}
};
point operator+ (const point& a,const point& b)
{
	return (point){a.x+b.x,a.y+b.y};
}
point operator- (const point& a,const point& b)
{
	return (point){a.x-b.x,a.y-b.y};
}
ftype dot(point a,point b)
{
	return a.x*b.x+a.y*b.y;
}
ftype cross(point a,point b)
{
	return a.x*b.y-a.y*b.x;
}
bool crossz(point a,point b)
{
	ftype x=a.x*b.y,y=a.y*b.x;
	__int128 xa=(x.a/base)*(y.b/base),xb=(x.a%base)*(y.b%base)+(x.a/base)*(y.b%base)*base+(x.a%base)*(y.b/base)*base;
	xa+=xb/base/base,xb%=base*base;
	__int128 ya=(y.a/base)*(x.b/base),yb=(y.a%base)*(x.b%base)+(y.a/base)*(x.b%base)*base+(y.a%base)*(x.b/base)*base;
	ya+=yb/base/base,yb%=base*base;
	return (xa>ya||(xa==ya&&xb>yb));
}
bool crosszz(point a,point b)
{
	ftype x=a.x*b.y,y=a.y*b.x;
	__int128 xa=(x.a/base)*(y.b/base),xb=(x.a%base)*(y.b%base)+(x.a/base)*(y.b%base)*base+(x.a%base)*(y.b/base)*base;
	xa+=xb/base/base,xb%=base*base;
	__int128 ya=(y.a/base)*(x.b/base),yb=(y.a%base)*(x.b%base)+(y.a/base)*(x.b%base)*base+(y.a%base)*(x.b/base)*base;
	ya+=yb/base/base,yb%=base*base;
	return (xa==ya&&xb==yb);
}
bool crossl(point a,point b)
{
	ftype x=a.x*b.y,y=a.y*b.x;
	__int128 xa=(x.a/base)*(y.b/base),xb=(x.a%base)*(y.b%base)+(x.a/base)*(y.b%base)*base+(x.a%base)*(y.b/base)*base;
	xa+=xb/base/base,xb%=base*base;
	__int128 ya=(y.a/base)*(x.b/base),yb=(y.a%base)*(x.b%base)+(y.a/base)*(x.b%base)*base+(y.a%base)*(x.b/base)*base;
	ya+=yb/base/base,yb%=base*base;
	return (xa<ya||(xa==ya&&xb<yb));
}
bool up(point a)
{
	if(a.y.a>0) return true;
	if(a.y.a==0&&a.x.a>0) return true;
	return false;
}
bool comp(pair<point,int> x,pair<point,int> y)
{
	point a=x.first,b=y.first;
	if(up(a)==up(b))
	{
		if(crosszz(a,b)) return x.second<y.second;
		return crossz(a,b);
	}
	return up(a)<up(b);
}
ftype ab(ftype res)
{
	__int128 g=__gcd(res.a,res.b);
	if(res.b/g<0) return {-res.a/g,-res.b/g};
	return {res.a/g,res.b/g};
}
point compress(int x,int y,int z)
{
	return {{x,x+y+z},{y,x+y+z}};
}
const int MAXN=2e5+5;
pair<point,int> val[MAXN];
point A[MAXN],B[MAXN];
int Q[MAXN],pos[MAXN];
set<int> st;
vector<__int128> vi[MAXN];
map< vector<__int128>,int > mp;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int x,y,z,q;
    cin>>x>>y>>z>>q;
    point a=compress(x,y,z);
    int cnt=0;
    for(int i=1;i<=q;i++)
    {
    	char c;
    	cin>>c;
    	if(c=='A')
    	{
    		int x,y,z;
    		cin>>x>>y>>z;
    		Q[i]=++cnt,val[cnt]={A[cnt]=compress(x,y,z)-a,cnt};
    		if(A[cnt].y.a==0) vi[cnt]={1,1,0,up(A[cnt])};
    		else vi[cnt]={ab(A[cnt].x/A[cnt].y).a,ab(A[cnt].x/A[cnt].y).b,1,up(A[cnt])};
		}
		else
		{
			int res;
			cin>>res;
			Q[i]=-res;
		}
	}
	sort(val+1,val+cnt+1,comp);
	for(int i=1;i<=cnt;i++) B[i]=val[i].first,pos[val[i].second]=i;
	int cnz=0,cc=0,crs=0,diff=0;
	long long cp=0;
	for(int i=1;i<=q;i++)
	{
		int p=abs(Q[i]);
		if(Q[i]>0)
		{
			cc++,cnz+=(A[p].x.a==0&&A[p].y.a==0);
			diff+=(mp[vi[p]]++==0),vi[p].back()^=1,cp+=mp[vi[p]],vi[p].back()^=1;
			st.insert(pos[p]);
			auto res=st.find(pos[p]);
			if(cc==2)
			{
				if(res==st.begin()) crs=(crossl(B[*res],B[*next(res)]))+(crossl(B[*next(res)],B[*res]));
				else crs=(crossl(B[*res],B[*prev(res)]))+(crossl(B[*prev(res)],B[*res]));
			}
			else if(cc>2)
			{
				int pl,pr;
				if(res==st.begin()) pl=*prev(st.end());
				else pl=*prev(res);
				if(res==prev(st.end())) pr=*st.begin();
				else pr=*next(res);
				crs-=(crossl(B[pl],B[pr]))-(crossl(B[pl],B[*res]))-(crossl(B[*res],B[pr]));
			}
		}
		else
		{
			cc--,cnz-=(A[p].x.a==0&&A[p].y.a==0);
			vi[p].back()^=1,cp-=mp[vi[p]],vi[p].back()^=1,diff-=(--mp[vi[p]]==0);
			auto res=st.find(pos[p]);
			if(cc==1) crs=0;
			else
			{
				int pl,pr;
				if(res==st.begin()) pl=*prev(st.end());
				else pl=*prev(res);
				if(res==prev(st.end())) pr=*st.begin();
				else pr=*next(res);
				crs+=(crossl(B[pl],B[pr]))-(crossl(B[pl],B[*res]))-(crossl(B[*res],B[pr]));
			}
			st.erase(pos[p]);
		}
		if(cnz) cout<<"1\n";
		else if(cp) cout<<"2\n";
		else if(diff-(cnz>0)>=3&&!crs) cout<<"3\n";
		else cout<<"0\n";
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...