bzoj1038 [ZJOI2008]瞭望塔
半平面交。
#include
#include
#include
using namespace std;
const double INF=1e100;
const double eps=1e-10;
const int N=305;
struct point
{
double x,y;
point(){}
point(double xx,double yy):x(xx),y(yy){}
inline point operator +(const point other)const
{
return point(x+other.x,y+other.y);
}
inline point operator -(const point other)const
{
return point(x-other.x,y-other.y);
}
inline point operator *(const double other)const
{
return point(x*other,y*other);
}
};
inline int dcmp(double a,double b)
{
if(fabs(a-b)return 0;
return a>b?1:-1;
}
inline double cross(point a,point b)
{
return a.x*b.y-b.x*a.y;
}
inline double supercross(point a,point b,point c)
{
return cross(point(b.x-a.x,b.y-a.y),point(c.x-b.x,c.y-b.y));
}
struct line
{
point s,v;
line(){}
line(point ss,point vv):s(ss),v(vv){}
inline bool operator <(const line other)const
{
double rate1=atan2(v.y,v.x),rate2=atan2(other.v.y,other.v.x);
if(!dcmp(rate1,rate2)) return dcmp(supercross(s,s+v,other.s),0)==-1;
else return rate1s-a.s;
double rate=cross(u,b.v)/cross(a.v,b.v);
return a.s+(a.v*rate);
}
inline bool onleft(line a,point p)
{
return dcmp(supercross(a.s,a.s+a.v,p),0)>0;
}
inline double high(point a,point b,double p)
{
return inter(line(a,b-a),line(point(p,0),point(0,1))).y;
}
struct halfinter
{
line a[N],q[N];
int n,h,t;
point tmp[N];
inline void solve()
{
sort(a+1,a+n+1);
q[h=t=1]=a[1];
for(int i=2;i<=n;i++)
{
if(!cross(a[i].v,a[i-1].v)) continue;
while(hq[t-1],q[t]))) t--;
while(hq[h],q[h+1]))) h++;
q[++t]=a[i];
}
while(h+1q[h],inter(q[t],q[t-1]))) t--;
while(h+1q[t],inter(q[h],q[h+1]))) h++;
for(int i=h;iq[i],q[i+1]);
}
}half;
int x[N],y[N];
int n;
double ans=INF;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&x[i]);
for(int i=1;i<=n;i++)
scanf("%d",&y[i]);
for(int i=1;ix[i],y[i]),point(x[i+1]-x[i],y[i+1]-y[i]));
half.n=n+1;
half.a[n]=line(point(x[1],0),point(0,-1));
half.a[n+1]=line(point(x[n],0),point(0,1));
half.solve();
for(int i=half.h,j=1;i<=half.t;i++)
{
while(dcmp(x[j],half.tmp[i].x)>0||dcmp(half.tmp[i].x,x[j+1])>0) j++;
ans=min(ans,half.tmp[i].y-high(point(x[j],y[j]),point(x[j+1],y[j+1]),half.tmp[i].x));
}
for(int i=1,j=half.h;i<=n;i++)
{
while(dcmp(half.tmp[j].x,x[i])>0||dcmp(x[i],half.tmp[j+1].x)>0) j++;
ans=min(ans,high(half.tmp[j],half.tmp[j+1],x[i])-y[i]);
}
printf("%.3lf",ans);
return 0;
}
cogs896
凸包。
#include
#include
#include
using namespace std;
const double eps=1e-10;
struct point
{
double x,y;
point(){}
point(double xx,double yy):x(xx),y(yy){}
inline point operator -(const point other)const
{
return point(x-other.x,y-other.y);
}
inline bool operator <(const point other)const
{
if(x==other.x) return yreturn x10005],s[10005];
int n,top;
double ans;
inline int dcmp(double a,double b)
{
if(fabs(a-b)return 0;
return a>b?1:-1;
}
inline double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
inline void solve()
{
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
while(top>1&&dcmp(cross(s[top]-s[top-1],a[i]-s[top-1]),0)<=0) top--;
s[++top]=a[i];
}
int num=top;
for(int i=n-1;i;i--)
{
while(top>num&&dcmp(cross(s[top]-s[top-1],a[i]-s[top-1]),0)<=0) top--;
s[++top]=a[i];
}
}
inline double sqr(double x){return x*x;}
int main()
{
freopen("fc.in","r",stdin);
freopen("fc.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
solve();
for(int i=1;isqrt(sqr(s[i].x-s[i+1].x)+sqr(s[i].y-s[i+1].y));
printf("%.2lf",ans);
return 0;
}
bzoj3165 [Heoi2013]Segment
李超线段树。
#include
#include
using namespace std;
#define pi pairint>
#define mod1 39989
#define mod2 1000000000
const int N=1e5+10;
inline void swap(int &a,int &b){a^=b,b^=a,a^=b;}
struct line
{
double k,b;
int l,r,id;
line(){}
line(int x1,int y1,int x2,int y2,int ID)
{
if(x1>x2) swap(x1,x2),swap(y1,y2);
if(x1==x2) k=0,b=max(y1,y2);
else k=(double)(y2-y1)/(double)(x2-x1),b=y1-k*x1;
l=x1,r=x2,id=ID;
}
inline double y(double x){return k*x+b;}
}t[N<<2];
int n,opt,x,y,z,w,ans,tot;
inline int point(line a,line b){return (b.b-a.b)/(a.k-b.k);}
void add(int l,int r,int now,line L)
{
if(L.l<=l&&r<=L.r)
{
if(L.y(l)>t[now].y(l)&&L.y(r)>t[now].y(r)){t[now]=L;return;}
if(L.y(l)<=t[now].y(l)&&L.y(r)<=t[now].y(r)) return;
int pos=point(L,t[now]),mid=(l+r)>>1;
if(pos<=mid)
if(L.y(r)>t[now].y(r)) add(l,mid,now<<1,t[now]),t[now]=L;
else add(l,mid,now<<1,L);
else
if(L.y(r)>t[now].y(r)) add(mid+1,r,now<<1|1,L);
else add(mid+1,r,now<<1|1,t[now]),t[now]=L;
return;
}
int mid=(l+r)>>1;
if(L.l<=mid) add(l,mid,now<<1,L);
if(L.r>mid) add(mid+1,r,now<<1|1,L);
}
pi ask(int p,int l,int r,int now)
{
if(l==r) return pi(t[now].y(p),t[now].id);
int mid=(l+r)>>1;pi ans;
if(p<=mid) ans=max(pi(t[now].y(p),t[now].id),ask(p,l,mid,now<<1));
else ans=max(pi(t[now].y(p),t[now].id),ask(p,mid+1,r,now<<1|1));
return ans;
}
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d",&opt);
if(opt)
{
scanf("%d%d%d%d",&x,&y,&z,&w);
x=(x+ans-1)%mod1+1,y=(y+ans-1)%mod2+1,
z=(z+ans-1)%mod1+1,w=(w+ans-1)%mod2+1;
add(1,40000,1,line(x,y,z,w,++tot));
}
else scanf("%d",&x),printf("%d\n",ans=ask((x+ans-1)%mod1+1,1,40000,1).second);
}
return 0;
}
bzoj1588 [HNOI2002]营业额统计
#include
#include
#include
#include
using namespace std;
const int N=(1<<15)+10;
struct tree
{
int maxn,minn;
}t[N<<2];
int a[N],tmp[N],s[N];
int n,ans,tot;
void build(int l,int r,int now)
{
t[now].maxn=1e9,t[now].minn=0;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,now<<1);
build(mid+1,r,now<<1|1);
}
inline void update(int now)
{
t[now].maxn=min(t[now<<1].maxn,t[now<<1|1].maxn);
t[now].minn=max(t[now<<1].minn,t[now<<1|1].minn);
}
void add(int p,int l,int r,int now)
{
if(l==r)
{
t[now].maxn=t[now].minn=p;
return;
}
int mid=(l+r)>>1;
if(p<=mid) add(p,l,mid,now<<1);
else add(p,mid+1,r,now<<1|1);
update(now);
}
int askmax(int L,int R,int l,int r,int now)
{
if(L<=l&&r<=R) return t[now].maxn;
int mid=(l+r)>>1,ans=1e9;
if(L<=mid) ans=askmax(L,R,l,mid,now<<1);
if(R>mid) ans=min(ans,askmax(L,R,mid+1,r,now<<1|1));
return ans;
}
int askmin(int L,int R,int l,int r,int now)
{
if(L<=l&&r<=R) return t[now].minn;
int mid=(l+r)>>1,ans=0;
if(L<=mid) ans=askmin(L,R,l,mid,now<<1);
if(R>mid) ans=max(ans,askmin(L,R,mid+1,r,now<<1|1));
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),s[i]=tmp[i]=a[i];
sort(tmp+1,tmp+n+1);
tot=unique(tmp+1,tmp+n+1)-tmp-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(tmp+1,tmp+tot+1,a[i])-tmp;
ans=s[1];
build(1,tot,1);
add(a[1],1,tot,1);
tmp[0]=1e9;
for(int i=2;i<=n;i++)
{
int x=askmax(a[i],tot,1,tot,1),y=askmin(1,a[i],1,tot,1);
if(x==1e9) ans+=abs(s[i]-tmp[y]);
else if(y==1e9) ans+=abs(s[i]-tmp[x]);
else ans+=min(abs(s[i]-tmp[x]),abs(s[i]-tmp[y]));
add(a[i],1,tot,1);
}
printf("%d",ans);
return 0;
}
bzoj3144 [Hnoi2013]切糕
#include
#include
#include
using namespace std;
#define pos(x,y,z) P*Q*(z-1)+(x-1)*Q+y
const int N=70005;
const int INF=1e9;
struct edge
{
int nxt,to,remain;
}a[N<<2];
int head[N],dis[N];
int P,Q,R,D,num=1,ans,S,T,x;
queue<int>q;
inline void add(int x,int y,int z)
{
a[++num].nxt=head[x],a[num].to=y,a[num].remain=z,head[x]=num;
a[++num].nxt=head[y],a[num].to=x,head[y]=num;
}
inline bool bfs()
{
memset(dis,0x3f,sizeof(dis));
dis[S]=0;q.push(S);
while(!q.empty())
{
int tmp=q.front();q.pop();
for(int i=head[tmp];i;i=a[i].nxt)
if(dis[a[i].to]>INF&&a[i].remain) dis[a[i].to]=dis[tmp]+1,q.push(a[i].to);
}
return dis[T]int dfs(int now,int limit)
{
if(now==T||!limit) return limit;
int flow=0,f;
for(int i=head[now];i;i=a[i].nxt)
if(dis[a[i].to]==dis[now]+1&&a[i].remain&&(f=dfs(a[i].to,min(limit,a[i].remain))))
{
flow+=f,limit-=f,a[i].remain-=f,a[i^1].remain+=f;
if(!limit) return flow;
}
dis[now]=-1;return flow;
}
inline int dinic(){int ans=0;while(bfs())ans+=dfs(S,INF);return ans;}
int main()
{
scanf("%d%d%d%d",&P,&Q,&R,&D);
S=P*Q*(R+1)+1,T=S+1;
for(int i=1;i<=P;i++)
for(int j=1;j<=Q;j++)
add(S,pos(i,j,1),INF),add(pos(i,j,R+1),T,INF);
for(int k=1;k<=R;k++)
for(int i=1;i<=P;i++)
for(int j=1;j<=Q;j++)
scanf("%d",&x),add(pos(i,j,k),pos(i,j,k+1),x);
for(int k=D+1;k<=R+1;k++)
for(int i=1;i<=P;i++)
for(int j=1;j<=Q;j++)
{
if(i!=P) add(pos(i,j,k),pos(i+1,j,k-D),INF);
if(i!=1) add(pos(i,j,k),pos(i-1,j,k-D),INF);
if(j!=Q) add(pos(i,j,k),pos(i,j+1,k-D),INF);
if(j!=1) add(pos(i,j,k),pos(i,j-1,k-D),INF);
}
printf("%d",dinic());
return 0;
}
bzoj2127 happiness
#include
#include
#include
#include
using namespace std;
#define pos(x,y) (x-1)*m+y
const int N=30005;
const int INF=1e9;
struct edge
{
int nxt,to,remain;
}a[N*15];
int head[N*15],dis[N*15];
int n,m,num=1,tot,x,S,T;
long long ans;
queue<int>q;
inline void add(int x,int y,int z)
{
a[++num].nxt=head[x],a[num].to=y,a[num].remain=z,head[x]=num;
a[++num].nxt=head[y],a[num].to=x,head[y]=num;
}
inline bool bfs()
{
memset(dis,0x3f,sizeof(dis));
dis[S]=0;q.push(S);
while(!q.empty())
{
int tmp=q.front();q.pop();
for(int i=head[tmp];i;i=a[i].nxt)
if(dis[a[i].to]>INF&&a[i].remain) dis[a[i].to]=dis[tmp]+1,q.push(a[i].to);
}
return dis[T]int dfs(int now,int limit)
{
if(now==T||!limit) return limit;
int flow=0,f;
for(int i=head[now];i;i=a[i].nxt)
if(dis[a[i].to]==dis[now]+1&&a[i].remain&&(f=dfs(a[i].to,min(limit,a[i].remain))))
{
flow+=f,limit-=f,a[i].remain-=f,a[i^1].remain+=f;
if(!limit) return flow;
}
dis[now]=-1;return flow;
}
inline int dinic(){int ans=0;while(bfs())ans+=dfs(S,INF);return ans;}
int main()
{
freopen("nt2011_happiness.in","r",stdin);
freopen("nt2011_happiness.out","w",stdout);
scanf("%d%d",&n,&m);
//1~mn:学生 mn+1~mn+(n-1)*m+(m-1)*n:加点
S=5*m*n-((m+n)<<1)+1,T=S+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&x),add(S,pos(i,j),x),ans+=x;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&x),add(pos(i,j),T,x),ans+=x;
tot=n*m;
for(int i=1;ifor(int j=1;j<=m;j++)
scanf("%d",&x),add(S,++tot,x),add(tot,pos(i,j),INF),add(tot,pos(i+1,j),INF),ans+=x;
for(int i=1;ifor(int j=1;j<=m;j++)
scanf("%d",&x),add(pos(i,j),++tot,INF),add(pos(i+1,j),tot,INF),add(tot,T,x),ans+=x;
for(int i=1;i<=n;i++)
for(int j=1;jscanf("%d",&x),add(S,++tot,x),add(tot,pos(i,j),INF),add(tot,pos(i,j+1),INF),ans+=x;
for(int i=1;i<=n;i++)
for(int j=1;jscanf("%d",&x),add(pos(i,j),++tot,INF),add(pos(i,j+1),tot,INF),add(tot,T,x),ans+=x;
printf("%lld",ans-dinic());
return 0;
}
bzoj0497 [NOI2006]最大获利
#include
#include
#include
#include
using namespace std;
const int N=55005;
const int INF=1e9;
struct edge
{
int nxt,to,remain;
}a[500005];
int dis[N],head[N];
int n,m,x,y,z,num=1,S,T,ans;
queue<int>q;
inline void add(int x,int y,int z)
{
a[++num].nxt=head[x],a[num].to=y,a[num].remain=z,head[x]=num;
a[++num].nxt=head[y],a[num].to=x,head[y]=num;
}
inline bool bfs()
{
memset(dis,0x3f,sizeof(dis));
dis[S]=0;q.push(S);
while(!q.empty())
{
int tmp=q.front();q.pop();
for(int i=head[tmp];i;i=a[i].nxt)
if(dis[a[i].to]>INF&&a[i].remain) dis[a[i].to]=dis[tmp]+1,q.push(a[i].to);
}
return dis[T]int dfs(int now,int limit)
{
if(now==T||!limit) return limit;
int flow=0,f;
for(int i=head[now];i;i=a[i].nxt)
if(dis[a[i].to]==dis[now]+1&&a[i].remain&&(f=dfs(a[i].to,min(limit,a[i].remain))))
{
flow+=f,limit-=f,a[i].remain-=f,a[i^1].remain+=f;
if(!limit) return flow;
}
dis[now]=-1;return flow;
}
inline int dinic(){int ans=0;while(bfs())ans+=dfs(S,INF);return ans;}
int main()
{
freopen("profit.in","r",stdin);
freopen("profit.out","w",stdout);
scanf("%d%d",&n,&m);
S=n+m+1,T=S+1;
for(int i=1;i<=n;i++)
scanf("%d",&x),add(m+i,T,x);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),add(S,i,z),add(i,m+x,INF),add(i,m+y,INF),ans+=z;
printf("%d",ans-dinic());
return 0;
}