【题目整理】

来源:互联网 发布:希捷数据恢复要多少钱 编辑:程序博客网 时间:2024/05/16 14:08

计算几何

bzoj1038 [ZJOI2008]瞭望塔

半平面交。

#include<cmath>#include<cstdio>#include<algorithm>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)<eps) 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 rate1<rate2;    }};inline point inter(line a,line b){    point u=b.s-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(h<t&&!onleft(a[i],inter(q[t-1],q[t]))) t--;            while(h<t&&!onleft(a[i],inter(q[h],q[h+1]))) h++;            q[++t]=a[i];        }        while(h+1<t&&!onleft(q[h],inter(q[t],q[t-1]))) t--;        while(h+1<t&&!onleft(q[t],inter(q[h],q[h+1]))) h++;        for(int i=h;i<t;i++)          tmp[i]=inter(q[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;i<n;i++)      half.a[i]=line(point(x[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<cmath>#include<cstdio>#include<algorithm>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 y<other.y;        return x<other.x;    }}a[10005],s[10005];int n,top;double ans;inline int dcmp(double a,double b){    if(fabs(a-b)<eps) 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;i<top;i++)      ans+=sqrt(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<cstdio>#include<iostream>using namespace std;#define pi pair<double,int>#define mod1 39989#define mod2 1000000000const 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<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>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<queue>#include<cstdio>#include<cstring>using namespace std;#define pos(x,y,z) P*Q*(z-1)+(x-1)*Q+yconst 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]<INF;}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<queue>#include<cstdio>#include<cstring>#include<iostream>using namespace std;#define pos(x,y) (x-1)*m+yconst 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]<INF;}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;i<n;i++)      for(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;i<n;i++)      for(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;j<m;j++)        scanf("%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;j<m;j++)        scanf("%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<queue>#include<cstdio>#include<cstring>#include<iostream>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]<INF;}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;}