【CSP-S 2019模拟】题解

T1:

线段树横竖模拟一下即可
本来以为atan2atan2过得了
结果被卡精度,只有30pts30pts
改成叉积就过了

#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define bg begin
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
cs int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int N=100005;
char xxx;
cs double eps=1e-9;
struct Seg{
	pii tag[N<<2];
	#define lc (u<<1)
	#define rc ((u<<1)|1)
	#define mid ((l+r)>>1)
	inline bool sign(double x,double y){
		return fabs(x-y)<eps;
	}
	inline pii comp(cs pii &a,cs pii &b){
		return (a.fi==b.fi)?(a.se>b.se?a:b):(a.fi<b.fi?a:b);
	}
	void build(int u,int l,int r){
		tag[u]=pii(1e9+5,0);
		if(l==r)return;
		build(lc,l,mid),build(rc,mid+1,r);
	}
	void update(int u,int l,int r,int st,int des,pii k){
		if(st>des)return;
		if(st<=l&&r<=des){tag[u]=comp(tag[u],k);return;}
		if(st<=mid)update(lc,l,mid,st,des,k);
		if(mid<des)update(rc,mid+1,r,st,des,k);
	}
	pii query(int u,int l,int r,int p){
		if(l==r)return tag[u];
		if(p<=mid)return comp(query(lc,l,mid,p),tag[u]);
		else return comp(query(rc,mid+1,r,p),tag[u]);
	}
	#undef lc
	#undef rc
	#undef mid
}tx,ty;
int m,cnt,n;
struct opt{
	int op,pos,lx,ly,rx,ry;
}q[N];
inline double P(double x){return x*x;}
struct pt{
	int x,y;
	pt(int _x=0,int _y=0):x(_x),y(_y){}
	friend inline ll operator *(cs pt &a,cs pt &b){
		return 1ll*a.x*b.y-1ll*a.y*b.x;
	}
	friend inline bool operator <(cs pt &a,cs pt &b){
		return a*b>0;
	}
	friend inline bool operator ==(cs pt &a,cs pt &b){
		return a.x==b.x&&a.y==b.y;
	}
}b[N];
char yyy;
int main(){
	m=read();
	for(int i=1;i<=m;i++){
		int op=read();q[i].op=op;
		if(op==1){
			q[i].lx=read(),q[i].ly=read(),q[i].rx=read(),q[i].ry=read();
		}
		else q[i].lx=read(),q[i].ly=read(),b[++n]=pt(q[i].lx,q[i].ly);
	}
	sort(b+1,b+n+1);
	cnt=unique(b+1,b+n+1)-b-1;
	tx.build(1,1,cnt),ty.build(1,1,cnt);
	for(int i=1;i<=m;i++)if(q[i].op==2)q[i].pos=lower_bound(b+1,b+cnt+1,pt(q[i].lx,q[i].ly))-b;
	for(int i=1;i<=m;i++){
		int op=q[i].op;
		if(op==1){
			int rp=upper_bound(b+1,b+cnt+1,pt(q[i].lx,q[i].ry))-b-1,lp=lower_bound(b+1,b+cnt+1,pt(q[i].lx,q[i].ly))-b;
			tx.update(1,1,cnt,lp,rp,pii(q[i].lx,i));
			rp=upper_bound(b+1,b+cnt+1,pt(q[i].lx,q[i].ly))-b-1,lp=lower_bound(b+1,b+cnt+1,pt(q[i].rx,q[i].ly))-b;
			ty.update(1,1,cnt,lp,rp,pii(q[i].ly,i));
		}
		else{
			pii nx=tx.query(1,1,cnt,q[i].pos),ny=ty.query(1,1,cnt,q[i].pos);
			if(nx.se==0||ny.se==0){cout<<nx.se+ny.se<<'
';continue;}
			double disx=0,disy=0;int last=0;
			if(q[i].lx==0)disx=P(q[nx.se].ly);
			else disx=(P(1.0*q[i].ly/q[i].lx)+1)*nx.fi*nx.fi;
			if(q[i].ly==0)disy=P(q[ny.se].lx);
			else disy=(P(1.0*q[i].lx/q[i].ly)+1)*ny.fi*ny.fi;
			if(disx+eps<disy)cout<<(last=nx.se)<<'
';
			else if(disx>eps+disy)cout<<(last=ny.se)<<'
';
			else cout<<(last=max(nx.se,ny.se))<<'
';
		}
	}
	return 0;
}

T2:

后缀自动机模板

#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define bg begin
#define pii pair<int,int>
#define fi first
#define se second
cs int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int N=500005;
char xxx;
int n,ans;
namespace Sam{
	cs int M=N*2;
	int fa[M],len[M],pos[M],mnpos[M],mxpos[M],tot,last;
	map<int,int>nxt[M];
	inline void init(){
		last=tot=1;
	}
	inline void insert(int c,int id){
		int cur=++tot,p=last;last=cur;
		len[cur]=len[p]+1,pos[cur]=mnpos[cur]=mxpos[cur]=id;
		for(;p&&!nxt[p].count(c);p=fa[p])nxt[p][c]=cur;
		if(!p)fa[cur]=1;
		else{
			int q=nxt[p][c];
			if(len[p]+1==len[q])fa[cur]=q;
			else {
				int clo=++tot;
				len[clo]=len[p]+1,nxt[clo]=nxt[q];
				fa[clo]=fa[q];
				for(;p&&nxt[p].count(c)&&nxt[p][c]==q;p=fa[p])nxt[p][c]=clo;
				fa[cur]=fa[q]=clo;
			}
		}
	}
	int buc[M],rk[M];
	inline void buc_sort(){
		for(int i=1;i<=tot;i++)buc[len[i]]++;
		for(int i=1;i<=tot;i++)buc[i]+=buc[i-1];
		for(int i=1;i<=tot;i++)rk[buc[len[i]]--]=i;
		for(int i=1;i<=tot;i++)if(!mnpos[i])mnpos[i]=1e9;
		for(int i=tot;i;i--){
			int u=rk[i];
			chemn(mnpos[fa[u]],mnpos[u]);
			chemx(mxpos[fa[u]],mxpos[u]);
			chemx(ans,min(mxpos[u]-mnpos[u],len[u]+1));
		}
	}
}
int a[N];
char yyy;
int main(){
	n=read(),Sam::init();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=n;i;i--)a[i]=a[i]-a[i-1];
	for(int i=2;i<=n;i++)Sam::insert(a[i],i);
	Sam::buc_sort();
	cout<<ans<<'
';
}

T3:

原题,LOJ6078LOJ6078

其实看到精度就应该想到迭代的
通过迭代来处理自环

由于O(deg2)=O(nm)O(deg^2)=O(nm)
然后可以考虑deg2deg^2对每个作为最小值的概率来dpdp

其实代码基本上就是对着zhoushuyuzhoushuyu的抄了一遍
也就懒得贴了

原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328384.html