UOJ # 191. [2016] Mutual Testing Team Unknown

UOJ # 191. [2016] Mutual Testing Team Unknown

Title Description

Solution

Binary groups.
Maintains a monotonically decreasing slope within the convex hull of each group.
Because there are deleted point, to avoid the complexity of the resulting explosion appears repeatedly cross jump, after the same depth range to fill a need to wait until the current consolidation range.
time complexity O ( n l g 2 n ) O (nlg '+2) .

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
struct Vct
{
	int x,y;
	Vct(int x1=0,int y1=0) { x=x1,y=y1; }
	Vct operator + (const Vct &a) { return Vct(x+a.x,y+a.y); }
	Vct operator - (const Vct &a) { return Vct(x-a.x,y-a.y); }
	ll operator * (const Vct &a) { return 1ll*x*a.y-1ll*y*a.x; }
	friend bool operator < (const Vct &a,const Vct &b) { return (a.x<b.x)||(a.x==b.x&&a.y<b.y); }
};
struct Convex_Hull
{
	vector<Vct> V;
	void Clear() { V.clear(); }
	Convex_Hull(){ Clear(); }
	void Push(Vct x) { int n=V.size(); while (n>=2&&(x-V[n-2])*(V[n-1]-V[n-2])<=0) V.pop_back(),n--; n++,V.PB(x); }
	friend Convex_Hull Merge(const Convex_Hull &x,const Convex_Hull &y)
	{
		Convex_Hull ans;
		int i,j;
		for (i=0,j=0;i<x.V.size()&&j<y.V.size();) ans.Push(x.V[i]<y.V[j]?x.V[i++]:y.V[j++]);
		for (;i<x.V.size();) ans.Push(x.V[i++]);
		for (;j<y.V.size();) ans.Push(y.V[j++]);
		return ans;
	}
	ll Query(Vct x)
	{
		int l=0,r=V.size()-1;
		while (l+5<r)
		{
			int mid=(l+r+1)>>1;
			if ((V[mid]-V[mid-1])*x<=0) l=mid;
			else r=mid-1;
		}
		ll ans=-loo;
		for (int i=l;i<=r;i++) upmax(ans,x*V[i]);
		return ans;
	}
};
struct Segment_Tree
{
	int flag[MAXN<<1],lst[20];
	Convex_Hull tree[MAXN<<1];
	void up(int x) { flag[x]=1,tree[x]=Merge(tree[x<<1],tree[x<<1|1]); }
	void build(int x,int l,int r,int dep)
	{
		lst[dep]=0;
		tree[x].Clear(),flag[x]=0;
		if (l==r) return;
		int mid=(l+r)>>1;
		build(x<<1,l,mid,dep+1);
		build(x<<1|1,mid+1,r,dep+1);
	}
	void insert(int x,int l,int r,int y,Vct z,int dep)
	{
		if (r==y)
		{
			if (lst[dep]) up(lst[dep]);
			lst[dep]=(l==r)?0:x;
		}
		if (l==r) { tree[x].Push(z); return; }
		int mid=(l+r)>>1;
		if (y<=mid) insert(x<<1,l,mid,y,z,dep+1);
		else insert(x<<1|1,mid+1,r,y,z,dep+1);
	}
	void erase(int x,int l,int r,int y,int dep)
	{
		tree[x].Clear(),flag[x]=0;
		if (lst[dep]==x) lst[dep]=0;
		if (l==r) return; 
		int mid=(l+r)>>1;
		if (y<=mid) erase(x<<1,l,mid,y,dep+1);
		else erase(x<<1|1,mid+1,r,y,dep+1);
	}
	ll query(int x,int l,int r,int L,int R,Vct y)
	{
		int mid=(l+r)>>1;
		if (L<=l&&r<=R) 
		{
			if (l==r||flag[x]) return tree[x].Query(y);
			return max(query(x<<1,l,mid,l,mid,y),query(x<<1|1,mid+1,r,mid+1,r,y));
		}
		if (R<=mid) return query(x<<1,l,mid,L,R,y);
		else if (L>mid) return query(x<<1|1,mid+1,r,L,R,y);
		else return max(query(x<<1,l,mid,L,mid,y),query(x<<1|1,mid+1,r,mid+1,R,y));
	}
} segment;
int main()
{
	int zbl=read(),Case;
	while (Case=read())
	{
		int n=min(300000,Case),num=0,ans=0;
		segment.build(1,1,n,0);
		while (Case--)
		{
			int opt=read();
			if (opt==1) { int x=read(),y=read(); segment.insert(1,1,n,++num,Vct(x,y),0); }
			else if (opt==2) { segment.erase(1,1,n,num--,0); }
			else 
			{
				int l=read(),r=read(),x=read(),y=read();
				ll t=segment.query(1,1,n,l,r,Vct(x,y));
				((t%=mods)+=mods)%=mods;
				ans^=t;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

Card space is very sick.

Published 94 original articles · won praise 6 · views 8518

Guess you like

Origin blog.csdn.net/xmr_pursue_dreams/article/details/104319356