# 2017 ACM-ICPC World Finals 题解

Problem L Visual Python++
bzoj4959

$O\left(nlogn\right)$$O(nlogn)$

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;

const int maxn = 210000;

int n;
int nx0[maxn],ny0[maxn],nx1[maxn],ny1[maxn],cntx,cnty;
struct point
{
int x,y,i,sig;
}p[maxn];
inline bool cmpx(const point x,const point y){return x.x<y.x;}
inline bool cmpy(const point x,const point y){return x.y==y.y?x.x<y.x:x.y<y.y;}

void Trans()
{
sort(p+1,p+2*n+1,cmpx); cntx=0;
for(int i=1,lax=-1;i<=2*n;i++)
{
if(lax!=p[i].x) cntx++;
lax=p[i].x,p[i].x=cntx;
}
sort(p+1,p+2*n+1,cmpy); cnty=0;
for(int i=1,lay=-1;i<=2*n;i++)
{
if(lay!=p[i].y) ++cnty;
lay=p[i].y,p[i].y=cnty;
}

for(int i=1;i<=2*n;i++)
{
int j=p[i].i;
if(p[i].sig==1) nx0[j]=p[i].x,ny0[j]=p[i].y;
else nx1[j]=p[i].x,ny1[j]=p[i].y;
}
}
int mat[maxn];
struct node
{
int x,i;
friend inline bool operator <(const node x,const node y){return x.x<y.x;}
};
set<node>S;
set<node>::iterator it;

struct Segment
{
int l,r,y,sig;
}a[maxn];
inline bool cmp(Segment x,Segment y){return x.y==y.y?x.sig<y.sig:x.y<y.y;}
struct Trb
{
int s[maxn],u;
int q(int x){int re=0;for(;x;x-=lowbit(x))re+=s[x];return re;}
}tr;

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x,y; scanf("%d%d",&x,&y);
p[i]=(point){x,y,i,1};
}
for(int i=n+1;i<=2*n;i++)
{
int x,y; scanf("%d%d",&x,&y);
p[i]=(point){x,y,i-n,-1};
}
Trans();

for(int i=1;i<=2*n;i++)
{
node tmp=(node){p[i].x,p[i].i};
if(p[i].sig==1) S.insert(tmp);
else
{
it=S.upper_bound(tmp);
if(it==S.begin()) return puts("syntax error"),0;
it--;
mat[(*it).i]=p[i].i;
S.erase(it);
}
}

for(int i=1;i<=n;i++)
{
int x=i,y=mat[i];
a[2*i-1]=(Segment){nx0[x],nx1[y],ny0[x],1};
a[2*i]=(Segment){nx0[x],nx1[y],ny1[y]+1,-1};
}
sort(a+1,a+2*n+1,cmp); tr.u=cntx;
for(int i=1;i<=2*n;i++)
{
else
{
int tmp=tr.q(a[i].r)-tr.q(a[i].l-1);
if(tmp) return puts("syntax error"),0;
}
}

for(int i=1;i<=n;i++)
{
int x=i,y=mat[i];
a[2*i-1]=(Segment){ny0[x],ny1[y],nx0[x],1};
a[2*i]=(Segment){ny0[x],ny1[y],nx1[y]+1,-1};
}
sort(a+1,a+2*n+1,cmp); tr.u=cnty;
for(int i=1;i<=2*n;i++)
{
else
{
int tmp=tr.q(a[i].r)-tr.q(a[i].l-1);
if(tmp) return puts("syntax error"),0;
}
}

for(int i=1;i<=n;i++) printf("%d\n",mat[i]);

return 0;
}

Problem K Tarot Sham Boast
bzoj4958

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 100005;
const int maxm = 12;

int n,m,len;
vector<int>V[maxm];
string s[maxm];
char str[maxn];
int nex[maxn];

int a[maxn];
inline int cmpv(const int x,const int y)
{
for(int i=0;i<V[x].size()&&i<V[y].size();i++) if(V[x][i]!=V[y][i])
return V[x][i]<V[y][i]?-1:1;
if(V[x].size()==V[y].size()) return 0;
return V[x].size()<V[y].size()?-1:1;
}
inline bool cmp(const int x,const int y)
{
int k=cmpv(x,y);
return k==0?x<y:(k<0);
}

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%s",str+1); len=strlen(str+1);
s[i].push_back(str[1]);
for(int j=2;j<=len;j++)
{
nex[j]=nex[j-1];
while(nex[j]&&str[nex[j]+1]!=str[j]) nex[j]=nex[nex[j]];
if(str[nex[j]+1]==str[j]) nex[j]++;
s[i].push_back(str[j]);
}
int k=nex[len];
while(k&&2*len-k<=n)
{
V[i].push_back(k);
k=nex[k];
}
a[i]=i;
}
sort(a+1,a+m+1,cmp);
for(int i=1;i<=m;i++) cout<<s[a[i]]<<endl;

return 0;
}

Problem J Son of Pipe Stream
bzoj4957

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;

const int maxn = 210;
const int maxm = 321000;
const double eps = 1e-9;

int n,m; double alpha,Vi;
struct edge{int y,nex; double c;}a[maxm]; int len,fir[maxn],fi[maxn];
inline void ins(const int x,const int y,const double c)
{
a[++len]=(edge){y,fir[x],c};fir[x]=len;
a[++len]=(edge){x,fir[y],0};fir[y]=len;
}
int e[maxm][3];
struct Max_Flow
{
int N,st,ed;
void Init()
{
len=1;
for(int i=0;i<=N;i++) fir[i]=0;
}
int h[maxn];
queue<int>q;
bool bfs()
{
for(int i=1;i<=N;i++) h[i]=0;
h[st]=1; q.push(st);
while(!q.empty())
{
const int x=q.front(); q.pop();
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(!h[y]&&a[k].c>0)
h[y]=h[x]+1,q.push(y);
}
return h[ed]>0;
}
double dfs(const int x,const double flow)
{
if(x==ed) return flow;
double delta=0;
for(int &k=fi[x],y=a[k].y;k;k=a[k].nex,y=a[k].y)
{
if(h[y]==h[x]+1&&a[k].c>0)
{
double minc=dfs(y,min(a[k].c,flow-delta));
a[k].c-=minc,a[k^1].c+=minc;
delta+=minc;
}
if(delta==flow) return delta;
}
return delta;
}
double Flow()
{
double ans=0;
while(bfs())
{
for(int i=1;i<=N;i++) fi[i]=fir[i];
ans+=dfs(st,inf);
}
return ans;
}
}Dicnic;

double F,W,Z,ans;
double val[maxm],ac[maxm],bc[maxm];

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d%d%lf%lf",&n,&m,&Vi,&alpha);
for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);

Dicnic.N=n+1; Dicnic.ed=3;

Dicnic.st=1; Dicnic.Init();
for(int i=1;i<=m;i++)
ins(e[i][0],e[i][1],e[i][2]),ins(e[i][1],e[i][0],e[i][2]);
F=Dicnic.Flow();

Dicnic.st=2; Dicnic.Init();
for(int i=1;i<=m;i++)
ins(e[i][0],e[i][1],e[i][2]),ins(e[i][1],e[i][0],e[i][2]);
W=Dicnic.Flow();

Dicnic.st=n+1,Dicnic.Init();
for(int i=1;i<=m;i++)
ins(e[i][0],e[i][1],e[i][2]),ins(e[i][1],e[i][0],e[i][2]);
ins(n+1,1,inf); ins(n+1,2,inf);
Z=Dicnic.Flow();
F=min(F,max(Z-W,alpha*Z));
W=Z-F;

Dicnic.Init();
for(int i=1;i<=m;i++)
ins(e[i][0],e[i][1],e[i][2]),ins(e[i][1],e[i][0],e[i][2]);
ins(n+1,1,F); ins(n+1,2,W);
Dicnic.Flow();
for(int i=1;i<=m;i++) val[i]=a[(i<<2)-1].c-a[(i<<2)+1].c;

Dicnic.Init();
for(int i=1;i<=m;i++)
val[i]>0?ins(e[i][0],e[i][1],val[i]):ins(e[i][1],e[i][0],-val[i]);
ins(n+1,1,F);
Dicnic.Flow();
for(int i=1;i<=m;i++)
ac[i]=a[i<<1|1].c*(val[i]>0?1:-1);

Dicnic.Init();
for(int i=1;i<=m;i++)
val[i]>0?ins(e[i][0],e[i][1],val[i]-ac[i]):ins(e[i][1],e[i][0],ac[i]-val[i]);
ins(n+1,2,W);
Dicnic.Flow();
for(int i=1;i<=m;i++)
bc[i]=a[i<<1|1].c*(val[i]>0?1:-1);

ans=pow(F,alpha)*pow(W,1.0-alpha)/pow(Vi,alpha);
for(int i=1;i<=m;i++) printf("%.8lf %.8lf\n",ac[i]/Vi+eps,bc[i]+eps);
printf("%.10lf\n",ans);

return 0;
}

Problem I Secret Chamber at Mount Rushmore
bzoj4956

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 30;
const int maxm = 1100;

int n,m;
int ind[maxn];
int v[maxn];

char str[110],s1[110],s2[110];

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
scanf("%s",str); int x=str[0]-'a';
scanf("%s",str); int y=str[0]-'a';
ind[y]|=1<<x;
}
for(int i=0;i<26;i++) v[i]=1<<i;
for(int i=0;i<26;i++)
{
int ok=1;
while(ok)
{
ok=0;
for(int j=0;j<26;j++) if(!(v[i]>>j&1)&&(ind[j]&v[i]))
ok++,v[i]|=v[j];
}
}
for(int i=1;i<=n;i++)
{
scanf("%s",s1); int l1=strlen(s1);
scanf("%s",s2); int l2=strlen(s2);
if(l1!=l2) { puts("no");continue; }
int ok=1;
for(int j=0;j<l1&&ok;j++)
if(!(v[s1[j]-'a']>>s2[j]-'a'&1)) ok=0;
puts(ok?"yes":"no");
}

return 0;
}

Problem H Scenery
bzoj4955
cf上过了bzoj上被卡常……
upd：bzoj上把时限从30s改到60s，35s跑过去了

$C$C则无解

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

inline void down(int &a,const int &b){if(a>b)a=b;}
const int maxn = 10010;

int n,T;
struct node
{
int l,r;
friend inline bool operator <(const node x,const node y){return x.l==y.l?x.r<y.r:x.l<y.l;}
}a[maxn];
int L[maxn],ln,R[maxn],rn;
int pre[maxn],fb[maxn],nowl[maxn];

void NIE(){ puts("no"); exit(0); }

int main()
{
scanf("%d%d",&n,&T);
for(int i=1;i<=n;i++)
{
int l,r; scanf("%d%d",&l,&r); r-=T;
L[i]=l,R[i]=r;
a[i].l=l,a[i].r=r;
}
sort(L+1,L+n+1);
for(int i=1;i<=n;i++) if(i==1||L[i]!=L[i-1]) L[++ln]=L[i];
sort(R+1,R+n+1);
for(int i=1;i<=n;i++) if(i==1||R[i]!=R[i-1]) R[++rn]=R[i];

for(int i=1;i<=ln;i++) fb[i]=L[i];
for(int i=1;i<=rn;i++) pre[i]=R[i]+T,nowl[i]=ln;
sort(a+1,a+n+1); int il=ln;
for(int i=n;i>=1;i--)
{
int ni=i-1;for(;ni>=1&&a[ni].l==a[i].l;ni--);ni++;
int nowj=i;
for(int j=rn;j>=1&&R[j]>=a[i].l;j--)
{
while(nowj>=ni&&a[nowj].r>R[j]) nowj--;
if(nowj<ni) break;
int c=nowj-ni+1;

int &k=pre[j],&ki=nowl[j];
while(c)
{
c--,k-=T;
while(k>=a[i].l)
{
while(L[ki-1]>k&&fb[ki]>=k) ki--;
if(k<L[ki]&&k>fb[ki]) k=fb[ki];
else break;
}
if(k<a[i].l) NIE();
}
down(fb[il],k-T);
}
i=ni; il--;
}
puts("yes");

return 0;
}

Problem G Replicate Replicate Rfplicbte
bzoj4954

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 310;

int nx,xx,ny,xy;
int X[maxn][maxn],Y[maxn][maxn];
int ans[maxn][maxn],ansx=-1,ansy;

void init()
{
//for(int i=ny;i<=xy+2;i++) for(int j=nx;j<=xx+2;j++) X[i][j]=0;
}
int Rec_lin()
{
for(int i=ny;i<=xy+1;i++)
{
for(int j=nx;j<=xx+2;j++) X[i][j]=Y[i-1][j-1]^X[i-2][j-2]^X[i-2][j-1]^X[i-2][j]^
X[i-1][j-2]^X[i-1][j-1]^X[i-1][j]^X[i][j-2]^X[i][j-1];
if(X[i][xx+1]+X[i][xx+2]>0) return i-1;
}
return 0;
}
int Rec_col()
{
for(int j=nx;j<=xx+1;j++)
{
for(int i=ny;i<=xy+2;i++) X[i][j]=Y[i-1][j-1]^X[i-2][j-2]^X[i-2][j-1]^X[i-2][j]^
X[i-1][j-2]^X[i-1][j-1]^X[i-1][j]^X[i][j-2]^X[i][j-1];
if(X[xy+1][j]+X[xy+2][j]>0) return j-1;
}
return 0;
}
void Dec()
{
for(;ny<xy;ny++)
{
int ok=0;
for(int j=nx;j<=xx;j++) ok+=X[ny][j];
if(ok) break;
}
for(;ny<xy;xy--)
{
int ok=0;
for(int j=nx;j<=xx;j++) ok+=X[xy][j];
if(ok) break;
}
for(;nx<xx;nx++)
{
int ok=0;
for(int i=ny;i<=xy;i++) ok+=X[i][nx];
if(ok) break;
}
for(;nx<xx;xx--)
{
int ok=0;
for(int i=ny;i<=xy;i++) ok+=X[i][xx];
if(ok) break;
}
}
void Copy()
{
for(int i=ny;i<=xy;i++) for(int j=nx;j<=xx;j++) Y[i][j]=X[i][j];
}
void upd()
{
ansx=xx-nx,ansy=xy-ny;
for(int i=0;i<=ansy;i++) for(int j=0;j<=ansx;j++)
ans[i][j]=Y[i+ny][j+nx];
}
void Print()
{
ny=0,xy=ansy;
nx=0,xx=ansx;
for(int i=ny;i<=xy;i++)
{
for(int j=nx;j<=xx;j++) putchar(ans[i][j]?'#':'.');
putchar('\n');
}
}

char str[maxn];

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

nx=ny=2; scanf("%d%d",&xx,&xy); xx++;xy++;
for(int i=ny;i<=xy;i++)
{
scanf("%s",str+nx);
for(int j=nx;j<=xx;j++) Y[i][j]=str[j]=='#';
}
for(upd();nx+1<xx&&ny+1<xy;init(),upd())
{
int y=Rec_lin();
if(y)
{
int x=Rec_col();
Y[y][x]^=1;
y=Rec_lin();
if(y) break;
}
Copy(); Dec();
}
Print();

return 0;
}

Problem F Posterize
bzoj4953

$f\left[i\right]\left[j\right]\left[k\right]$$f[i][j][k]$表示dp到像素$i$$i$，上一个特殊点取的是$j$$j$，已经用了$k$$k$个特殊点的最优解，转移用前缀和优化一下

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e15
using namespace std;

inline void down(ll &a,const ll &b){if(a==-1||a>b)a=b;}
const int maxn = 300;

int n,K;
int pi[maxn];
ll f[2][maxn][maxn],s[maxn][maxn];

ll sqr(int x){ return (ll)x*x; }

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d%d",&n,&K);
for(int i=1;i<=n;i++)
{
int x; scanf("%d",&x);
scanf("%d",&pi[x]);
}

for(int i=0;i<256;i++)
{
s[i][0]=sqr(i)*pi[0];
for(int j=1;j<256;j++) s[i][j]=s[i][j-1]+sqr(i-j)*pi[j];
}

int now=0; memset(f,-1,sizeof f);
f[now][0][0]=0;
for(int i=0;i<256;i++)
{
now=!now;
for(int j=0;j<256;j++) for(int k=0;k<=K;k++) if(f[!now][j][k]!=-1)
{
ll &temp=f[!now][j][k];
down(f[now][j][k],temp);
if(!k) down(f[now][i][k+1],temp+s[i][i]);
else
{
int mid=(i+j)>>1;
down(f[now][i][k+1],temp+s[j][mid]-s[j][j]+s[i][i]-s[i][mid]);
}
temp=-1;
}
}
ll ans=inf;
for(int i=0;i<256;i++) if(f[now][i][K]!=-1)
down(ans,f[now][i][K]+s[i][255]-s[i][i]);
printf("%lld\n",ans);

return 0;
}

Problem E Need for Speed
bzoj4952

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9+1
using namespace std;

const int maxn = 1100;
const double eps = 1e-9;

int n,t;
int di[maxn],si[maxn];

double cal(double mid)
{
double re=0;
for(int i=1;i<=n;i++)
{
double c=si[i]+mid;
if(c<eps) return inf;
re+=di[i]/c;
}
return re;
}

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d%d",&n,&t);
for(int i=1;i<=n;i++) scanf("%d%d",&di[i],&si[i]);

double l=-inf,r=inf;
while(r-l>eps)
{
double mid=(l+r)/2.0;
if(cal(mid)>t) l=mid;
else r=mid;
}
printf("%.10lf\n",l);

return 0;
}

Problem D Money for Nothing
bzoj4951

$O\left(nlogn\right)$$O(nlogn)$分治

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;

{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
inline void up(int &a,const int &b){if(a<b)a=b;}
inline void down(int &a,const int &b){if(a>b)a=b;}
const int maxn = 1010000;

int n,m;
struct node
{
int x,y;
friend inline bool operator <(const node x,const node y){return x.x<y.x;}
}a[maxn],b[maxn];
int L[maxn],ln,lc[maxn];
int R[maxn],rn,rc[maxn];

int tlp[maxn],tl[maxn],tln;
int trp[maxn],tr[maxn],trn;

ll ans;
void Solve(int l,int r,int ql,int qr)
{
if(l>r) return;

int mid=(l+r)>>1;
ll tmp=LLONG_MIN,tmpi;
for(int i=ql;i<=qr;i++) if(trp[mid]>tlp[i])
{
ll now=(ll)(trp[mid]-tlp[i])*(tr[mid]-tl[i]);
if(tmp<now) tmp=now,tmpi=i;
}
if(ans<tmp) ans=tmp;
Solve(l,mid-1,ql,tmpi);
Solve(mid+1,r,tmpi,qr);
}

int main()
{

sort(L+1,L+n+1); ln=0;
for(int i=1;i<=n;i++) if(i==1||L[i]!=L[i-1]) L[++ln]=L[i],lc[ln]=inf;
sort(a+1,a+n+1);
for(int i=1,nl=0;i<=n;i++)
{
if(i==1||a[i].x!=a[i-1].x) nl++;
down(lc[nl],a[i].y);
}

for(int i=1;i<=ln;i++)
{
if(tln&&tl[tln]<=lc[i]) continue;
tln++;
tlp[tln]=L[i],tl[tln]=lc[i];
}

sort(R+1,R+m+1); rn=0;
for(int i=1;i<=m;i++) if(i==1||R[i]!=R[i-1]) R[++rn]=R[i],rc[rn]=0;
sort(b+1,b+m+1);
for(int i=1,nr=0;i<=m;i++)
{
if(i==1||b[i].x!=b[i-1].x) nr++;
up(rc[nr],b[i].y);
}

for(int i=1;i<=rn;i++)
{
while(trn&&tr[trn]<=rc[i]) trn--;
trn++;
trp[trn]=R[i],tr[trn]=rc[i];
}

while(tln&&tlp[tln]>=trp[trn]) tln--;
int pos=1;
while(pos<=trn&&trp[pos]<=tlp[1]) pos++;
for(int i=pos;i<=trn;i++) tr[i-pos+1]=tr[i],trp[i-pos+1]=trp[i];
trn-=pos-1;

Solve(1,trn,1,tln);
printf("%lld\n",ans);

return 0;
}

Problem C Mission Improbable
bzoj4950

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e18
using namespace std;

{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
inline void up(int &a,const int &b){if(a<b)a=b;}
const int maxl = 110;
const int maxn = 1100;
const int maxm = 210000;

int n,m;
int ci[maxl][maxl],xl[maxn],xc[maxn];
struct edge{int y,c,d,nex;}a[maxm]; int len,fir[maxn];
inline void ins(const int x,const int y,const int c,const int d)
{
a[++len]=(edge){y,c,d,fir[x]};fir[x]=len;
a[++len]=(edge){x,0,-d,fir[y]};fir[y]=len;
}
struct Max_Flow
{
void init()
{
len=1;
for(int i=1;i<=n+m+2;i++) fir[i]=0;
}
int st,ed;
ll dis[maxn];
int pos[maxn],pre[maxn];
queue<int>q; int insta[maxn];
bool bfs()
{
for(int i=1;i<=ed;i++) dis[i]=inf;
dis[st]=0; q.push(st);
while(!q.empty())
{
const int x=q.front(); q.pop(); insta[x]=0;
for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(a[k].c&&dis[y]>dis[x]+a[k].d)
{
dis[y]=dis[x]+a[k].d;
pos[y]=x,pre[y]=k;
if(!insta[y]) insta[y]=1,q.push(y);
}
}
return dis[ed]!=inf;
}
ll Flow()
{
ll ans=0;
while(bfs())
{
if(dis[ed]>0) break;
ans+=dis[ed];
for(int i=ed;i!=st;i=pos[i]) a[pre[i]].c--,a[pre[i]^1].c++;
}
return ans;
}
}flow;

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
up(xl[i],ci[i][j]);
up(xc[j],ci[i][j]);
}
}

ll ans=0;
flow.init(); flow.st=n+m+1,flow.ed=n+m+2;
for(int i=1;i<=n;i++) if(xl[i]) ins(flow.st,i,1,0);
for(int i=1;i<=m;i++) if(xc[i]) ins(n+i,flow.ed,1,0);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++) if(ci[i][j])
{
ans++;
if(xl[i]==xc[j]) ins(i,n+j,1,-(xl[i]-1));
}
}
for(int i=1;i<=n;i++) if(xl[i]) ans+=xl[i]-1;
for(int i=1;i<=m;i++) if(xc[i]) ans+=xc[i]-1;
ans+=flow.Flow();
printf("%lld\n",sum-ans);

return 0;
}

Problem B Get a Clue!
bzoj4949

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 55;

int n;
int v0;
int qp[maxn],qi[maxn],rd[maxn][4];

int judge(int x,int s)
{
for(int i=1;i<=n;i++)
{
for(int j=(qp[i]+1)&3;j!=qp[i];j=(j+1)&3)
{
if(j==x)
{
if(rd[i][j]==-1)
{
if(s&qi[i]) return 0;
}
else
{
if(qp[i]==0)
{
if(!(s>>rd[i][j]&1)) return 0;
}
else
{
if(!(s&qi[i])) return 0;
}
}
}
else if(rd[i][j]!=-1&&(qi[i]&s)==qi[i]) return 0;
if(rd[i][j]!=-1) break;
}
}
return 1;
}
int po(int i,int j,int k)
{
int x=1<<i|1<<j|1<<k;
if(x&v0) return 0;
for(int s=Oth;s;s=(s-1)&Oth) if(v[0][s])
{
int oth=Oth^s;
for(int t=oth;t;t=(t-1)&oth) if(v[1][t])
if(v[2][oth^t]) return 1;
}
return 0;
}
int ok[3][30];
void Print()
{
int sum=0,la;
for(int i=0;i<6;i++) if(ok[0][i]) sum++,la=i;
putchar(sum==1?'A'+la:'?');
sum=0;
for(int i=0;i<6;i++) if(ok[1][i]) sum++,la=i;
putchar(sum==1?'A'+6+la:'?');
sum=0;
for(int i=0;i<9;i++) if(ok[2][i]) sum++,la=i;
putchar(sum==1?'A'+12+la:'?');
putchar('\n');
}

char str[10];

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d",&n);
for(int i=0;i<5;i++)
{
scanf("%s",str); int x=str[0]-'A';
v0|=1<<x;
}
qp[0]=3; memset(rd,-1,sizeof rd);
for(int i=1;i<=n;i++)
{
qp[i]=(qp[i-1]+1)&3;
for(int j=0;j<3;j++)
{
scanf("%s",str); int x=str[0]-'A';
qi[i]|=1<<x;
}
for(int j=(qp[i]+1)&3;j!=qp[i];j=(j+1)&3)
{
scanf("%s",str);
if(str[0]!='-')
{
rd[i][j]=!qp[i]?str[0]-'A':0;
break;
}
}
}
{
int num=__builtin_popcount(i);
if(num==5) v[0][i]=judge(1,i);
if(num==4) v[1][i]=judge(2,i),v[2][i]=judge(3,i);
}

for(int i=0;i<6;i++) for(int j=0;j<6;j++) for(int k=0;k<9;k++) if(po(i,6+j,12+k))
ok[0][i]=ok[1][j]=ok[2][k]=1;
Print();

return 0;
}

Problem A Airport Construction
bzoj4948

code：

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<algorithm>
#define ll long long
#define ld long double
using namespace std;

const int maxn = 205;
const ld eps = 1e-8;

int n;
struct Point
{
ld x,y;
Point operator +(const Point &b){ return (Point){x+b.x,y+b.y}; }
Point operator -(const Point &b){ return (Point){x-b.x,y-b.y}; }
ld operator *(const Point &b)
{
return x*b.y-y*b.x;
}
inline ld Len() { return sqrt(x*x+y*y); }
}a[maxn];

struct Line
{
Point a,b;
Line(){}
Line(const Point &_a,const Point &_b){a=_a,b=_b;}
inline ld Dis(Line l)
{
return (l.a-a)*(l.b-a)/((l.b-l.a)*(b-a))*(b-a).Len();
}
};
pair<ld,int>t[maxn]; int tp;
ld ans;

inline int Sgn(ld x){ return fabs(x)<eps?0:(x<0?-1:1); }
void Solve(Line l)
{
tp=0;
for(int i=1;i<=n;i++)
{
Line r=(Line){a[i-1],a[i]};
int p=Sgn((l.b-l.a)*(r.a-l.a)),q=Sgn((l.b-l.a)*(r.b-l.a));
if(p==q) continue;
if(p>q) t[++tp]=make_pair(l.Dis(r),p&&q?2:1);
else t[++tp]=make_pair(l.Dis(r),p&&q?-2:-1);
}
sort(t+1,t+tp+1);
int cur=0; ld len=0;
for(int i=1;i<=tp;i++)
{
if(cur) len+=t[i].first-t[i-1].first;
else ans=max(ans,len),len=0;
cur+=t[i].second;
}
ans=max(ans,len);
}

int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);

scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%Lf%Lf",&a[i].x,&a[i].y);
a[n]=a[0];

for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++) Solve(Line(a[i],a[j]));
printf("%.10Lf\n",ans);

return 0;
}