The 20th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
题解:
https://files.cnblogs.com/files/clrs97/2023_ZJCPC_Tutorial.pdf
Code:
A. Look and Say
#include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); int n; cin>>n; string s; cin>>s; char pre=' '; int cnt=0; for(auto ch:s) { if(ch==pre)cnt++; else { if(cnt)cout<<cnt<<pre; pre=ch;cnt=1; } } cout<<cnt<<pre; return 0; }
B. Master of Polygon
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=200005,M=200005,K=17,inf=~0U>>1; int n,m,cq,i,xl,xr; bool ans[M]; int idseg[K][N],idque[K][M]; struct P{ int x,y; P(){} P(int _x,int _y){x=_x,y=_y;} P operator-(const P&b)const{return P(x-b.x,y-b.y);} P operator+(const P&b)const{return P(x+b.x,y+b.y);} ll operator*(const P&b)const{return 1LL*x*b.x+1LL*y*b.y;} bool operator==(const P&b)const{return x==b.x&&y==b.y;} void read(){scanf("%d%d",&x,&y);} }a[N]; struct Line{ P a,b; int xl,xr; int sx,sy,dx,dy; ll base; void fix(){ if(a.x>b.x)swap(a,b); xl=a.x,xr=b.x; sx=a.x,sy=a.y,dx=b.x-a.x,dy=b.y-a.y; base=1LL*sy*dx-1LL*sx*dy; } }seg[N],que[M]; struct Frac{ ll u,d; Frac(){} Frac(ll _u,ll _d){ u=_u,d=_d; if(d<0)u*=-1,d*=-1; } bool operator<(const Frac&b)const{return u*b.d<b.u*d;} bool operator>(const Frac&b)const{return u*b.d>b.u*d;} bool operator<=(const Frac&b)const{return u*b.d<=b.u*d;} bool operator>=(const Frac&b)const{return u*b.d>=b.u*d;} }slo[M]; inline int sgn(ll x){ if(x>0)return 1; return x?-1:0; } inline ll cross(const P&a,const P&b){return 1LL*a.x*b.y-1LL*a.y*b.x;} inline void umin(int&a,int b){a>b?(a=b):0;} inline void umax(int&a,int b){a<b?(a=b):0;} inline Frac gety(const Line&a,int x){ if(a.dx==0)return Frac(a.sy,1); return Frac(a.base+1LL*x*a.dy,a.dx); } inline bool point_on_segment(const P&p,const P&a,const P&b){ return cross(b-a,p-a)==0&&(p-a)*(p-b)<=0; } inline bool has_intersection(const Line&A,const Line&B){ if(!A.dx&&!A.dy)return point_on_segment(A.a,B.a,B.b); const P&a=A.a; const P&b=A.b; const P&p=B.a; const P&q=B.b; int d1=sgn(cross(b-a,p-a)),d2=sgn(cross(b-a,q-a)); int d3=sgn(cross(q-p,a-p)),d4=sgn(cross(q-p,b-p)); if(d1*d2<0&&d3*d4<0)return 1; if((d1==0&&point_on_segment(p,a,b))|| (d2==0&&point_on_segment(q,a,b))|| (d3==0&&point_on_segment(a,p,q))|| (d4==0&&point_on_segment(b,p,q)))return 1; return 0; } namespace CaseWholeSeg{ int cnt,q[N]; inline void init(){cnt=0;} inline void add(int x){q[++cnt]=x;} inline bool cmpseg(int A,int B){ const Line&p=seg[A]; const Line&q=seg[B]; int x=p.a==q.a?min(p.xr,q.xr):max(p.xl,q.xl); return gety(p,x)<gety(q,x); } inline void work(){sort(q+1,q+cnt+1,cmpseg);} inline bool ask(const Line&p){ int l=1,r=cnt,mid; while(l<=r){ mid=(l+r)>>1; const Line&o=seg[q[mid]]; if(has_intersection(p,o))return 1; int x=max(p.xl,o.xl); if(gety(p,x)<gety(o,x))r=mid-1;else l=mid+1; } return 0; } } namespace CaseWholeQue{ int xl,xr; int cs,idseg[N]; int cq,idque[M]; Frac yl[M],yr[M]; int cnt,cp,cl,cr,idl[N],idr[N]; P pool[N*2]; int ccur,chull; struct Component{ int st,en; bool isl,isr; Frac lmi,lma,rmi,rma; void upl(const Frac&b){ if(!isl){ isl=1; lmi=lma=b; return; } if(lmi>b)lmi=b; if(lma<b)lma=b; } void upr(const Frac&b){ if(!isr){ isr=1; rmi=rma=b; return; } if(rmi>b)rmi=b; if(rma<b)rma=b; } }com[N]; struct Point{ int x;Frac y; Point(){} Point(const P&b){x=b.x,y=Frac(b.y,1);} Point(int _x,const Frac&_y){x=_x,y=_y;} }cur[N*2],hull[N*2]; inline bool cmpx(const P&a,const P&b){return a.x<b.x;} inline void init(int _xl,int _xr){xl=_xl,xr=_xr;cs=cq=0;} inline void addseg(int x){idseg[++cs]=x;} inline void addque(int x){ idque[++cq]=x; yl[x]=gety(que[x],xl); yr[x]=gety(que[x],xr); } inline Frac slope(const Point&a,const Point&b){//a.x<b.x return Frac(b.y.u*a.y.d-a.y.u*b.y.d,(b.x-a.x)*a.y.d*b.y.d); } namespace CaseLeft{ inline bool cmpyl(int x,int y){return yl[x]<yl[y];} inline bool cmplma(int x,int y){return com[x].lma<com[y].lma;} inline bool cmplmi(int x,int y){return com[x].lmi>com[y].lmi;} inline void ext_down(int&n,Point*q,const Point&p){ if(n&&q[n].x==p.x){ if(q[n].y>=p.y)return; n--; } while(n>1&&slope(p,q[n])<=slope(q[n],q[n-1]))n--; q[++n]=p; } inline bool notin_down(const Point&p){ if(chull<=1)return 1; if(p.x>hull[1].x)return 1; int l=2,r=chull-1,t=1; while(l<=r){ int mid=(l+r)>>1; if(p.x==hull[mid].x)return p.y>=hull[mid].y; if(p.x>hull[mid].x)r=mid-1;else l=(t=mid)+1; } return slope(hull[t+1],p)>=slope(p,hull[t]); } inline void ext_up(int&n,Point*q,const Point&p){ if(n&&q[n].x==p.x){ if(q[n].y<=p.y)return; n--; } while(n>1&&slope(p,q[n])>=slope(q[n],q[n-1]))n--; q[++n]=p; } inline bool notin_up(const Point&p){ if(chull<=1)return 1; if(p.x>hull[1].x)return 1; int l=2,r=chull-1,t=1; while(l<=r){ int mid=(l+r)>>1; if(p.x==hull[mid].x)return p.y<=hull[mid].y; if(p.x>hull[mid].x)r=mid-1;else l=(t=mid)+1; } return slope(hull[t+1],p)<=slope(p,hull[t]); } inline void solve(){ if(!cl)return; int i,j,k,A,B; sort(idque+1,idque+cq+1,cmpyl); sort(idl+1,idl+cl+1,cmplma); //left Frac minl; for(i=cq,j=cl;i;i--){ A=idque[i]; if(ans[A])continue; while(j){ B=idl[j]; if(com[B].lma<yl[A])break; if(j==cl)minl=com[B].lmi; else if(minl>com[B].lmi)minl=com[B].lmi; j--; } if(j<cl&&minl<=yl[A])ans[A]=1; } //down chull=0; for(i=j=1;i<=cq;i++){ A=idque[i]; if(ans[A])continue; while(j<=cl){ B=idl[j]; if(com[B].lma>=yl[A])break; ccur=0; if(com[B].isr)ext_down(ccur,cur,Point(xr,com[B].rma)); for(k=com[B].en;k>=com[B].st;k--)ext_down(ccur,cur,pool[k]); ext_down(ccur,cur,Point(xl,com[B].lma)); if(com[B].isr){ chull=ccur; for(k=1;k<=ccur;k++)hull[k]=cur[k]; }else{ k=ccur; while(k>1&¬in_down(cur[k-1]))k--; while(chull&&hull[chull].x<=cur[k].x)chull--; for(;k<=ccur;k++)ext_down(chull,hull,cur[k]); } j++; } if(chull<=1)continue; int l=1,r=chull-1; if(hull[1].x==xr){ if(hull[1].y>=yr[A]){ ans[A]=1; continue; } if(chull==2)continue; l++; } int t=r--; const Frac&v=slo[A]; //min slope(hull[t+1],hull[t]) >= v while(l<=r){ int mid=(l+r)>>1; if(slope(hull[mid+1],hull[mid])>=v)r=(t=mid)-1;else l=mid+1; } if(slope(que[A].a,hull[t])>=slope(hull[t],que[A].b))ans[A]=1; } //up sort(idl+1,idl+cl+1,cmplmi); chull=0; for(i=cq,j=1;i;i--){ A=idque[i]; if(ans[A])continue; while(j<=cl){ B=idl[j]; if(com[B].lmi<=yl[A])break; ccur=0; if(com[B].isr)ext_up(ccur,cur,Point(xr,com[B].rmi)); for(k=com[B].en;k>=com[B].st;k--)ext_up(ccur,cur,pool[k]); ext_up(ccur,cur,Point(xl,com[B].lmi)); if(com[B].isr){ chull=ccur; for(k=1;k<=ccur;k++)hull[k]=cur[k]; }else{ k=ccur; while(k>1&¬in_up(cur[k-1]))k--; while(chull&&hull[chull].x<=cur[k].x)chull--; for(;k<=ccur;k++)ext_up(chull,hull,cur[k]); } j++; } if(chull<=1)continue; int l=1,r=chull-1; if(hull[1].x==xr){ if(hull[1].y<=yr[A]){ ans[A]=1; continue; } if(chull==2)continue; l++; } int t=r--; const Frac&v=slo[A]; while(l<=r){ int mid=(l+r)>>1; if(slope(hull[mid+1],hull[mid])<=v)r=(t=mid)-1;else l=mid+1; } if(slope(que[A].a,hull[t])<=slope(hull[t],que[A].b))ans[A]=1; } } } namespace CaseRight{ inline bool cmpyr(int x,int y){return yr[x]<yr[y];} inline bool cmprma(int x,int y){return com[x].rma<com[y].rma;} inline bool cmprmi(int x,int y){return com[x].rmi>com[y].rmi;} inline void ext_down(int&n,Point*q,const Point&p){ if(n&&q[n].x==p.x){ if(q[n].y>=p.y)return; n--; } while(n>1&&slope(q[n],p)>=slope(q[n-1],q[n]))n--; q[++n]=p; } inline bool notin_down(const Point&p){ if(chull<=1)return 1; if(p.x<hull[1].x)return 1; int l=2,r=chull-1,t=1; while(l<=r){ int mid=(l+r)>>1; if(p.x==hull[mid].x)return p.y>=hull[mid].y; if(p.x<hull[mid].x)r=mid-1;else l=(t=mid)+1; } return slope(hull[t],p)>=slope(p,hull[t+1]); } inline void ext_up(int&n,Point*q,const Point&p){ if(n&&q[n].x==p.x){ if(q[n].y<=p.y)return; n--; } while(n>1&&slope(q[n],p)<=slope(q[n-1],q[n]))n--; q[++n]=p; } inline bool notin_up(const Point&p){ if(chull<=1)return 1; if(p.x<hull[1].x)return 1; int l=2,r=chull-1,t=1; while(l<=r){ int mid=(l+r)>>1; if(p.x==hull[mid].x)return p.y<=hull[mid].y; if(p.x<hull[mid].x)r=mid-1;else l=(t=mid)+1; } return slope(hull[t],p)<=slope(p,hull[t+1]); } inline void solve(){ if(!cr)return; int i,j,k,A,B; sort(idque+1,idque+cq+1,cmpyr); sort(idr+1,idr+cr+1,cmprma); //right Frac minl; for(i=cq,j=cr;i;i--){ A=idque[i]; if(ans[A])continue; while(j){ B=idr[j]; if(com[B].rma<yr[A])break; if(j==cr)minl=com[B].rmi; else if(minl>com[B].rmi)minl=com[B].rmi; j--; } if(j<cr&&minl<=yr[A])ans[A]=1; } //down chull=0; for(i=j=1;i<=cq;i++){ A=idque[i]; if(ans[A])continue; while(j<=cr){ B=idr[j]; if(com[B].rma>=yr[A])break; ccur=0; if(com[B].isl)ext_down(ccur,cur,Point(xl,com[B].lma)); for(k=com[B].st;k<=com[B].en;k++)ext_down(ccur,cur,pool[k]); ext_down(ccur,cur,Point(xr,com[B].rma)); if(com[B].isl){ chull=ccur; for(k=1;k<=ccur;k++)hull[k]=cur[k]; }else{ k=ccur; while(k>1&¬in_down(cur[k-1]))k--; while(chull&&hull[chull].x>=cur[k].x)chull--; for(;k<=ccur;k++)ext_down(chull,hull,cur[k]); } j++; } if(chull<=1)continue; int l=1,r=chull-1; if(hull[1].x==xl){ if(hull[1].y>=yl[A]){ ans[A]=1; continue; } if(chull==2)continue; l++; } int t=r--; const Frac&v=slo[A]; //min slope(hull[t],hull[t+1]) <= v while(l<=r){ int mid=(l+r)>>1; if(slope(hull[mid],hull[mid+1])<=v)r=(t=mid)-1;else l=mid+1; } if(slope(que[A].a,hull[t])>=slope(hull[t],que[A].b))ans[A]=1; } //up sort(idr+1,idr+cr+1,cmprmi); chull=0; for(i=cq,j=1;i;i--){ A=idque[i]; if(ans[A])continue; while(j<=cr){ B=idr[j]; if(com[B].rmi<=yr[A])break; ccur=0; if(com[B].isl)ext_up(ccur,cur,Point(xl,com[B].lmi)); for(k=com[B].st;k<=com[B].en;k++)ext_up(ccur,cur,pool[k]); ext_up(ccur,cur,Point(xr,com[B].rmi)); if(com[B].isl){ chull=ccur; for(k=1;k<=ccur;k++)hull[k]=cur[k]; }else{ k=ccur; while(k>1&¬in_up(cur[k-1]))k--; while(chull&&hull[chull].x>=cur[k].x)chull--; for(;k<=ccur;k++)ext_up(chull,hull,cur[k]); } j++; } if(chull<=1)continue; int l=1,r=chull-1; if(hull[1].x==xl){ if(hull[1].y<=yl[A]){ ans[A]=1; continue; } if(chull==2)continue; l++; } int t=r--; const Frac&v=slo[A]; //min slope(hull[t],hull[t+1]) >= v while(l<=r){ int mid=(l+r)>>1; if(slope(hull[mid],hull[mid+1])>=v)r=(t=mid)-1;else l=mid+1; } if(slope(que[A].a,hull[t])<=slope(hull[t],que[A].b))ans[A]=1; } } } inline void work(){ if(!cs||!cq)return; int i,j,k,x; static int q[N]; static bool vis[N],is[N]; for(i=1;i<=cs;i++){ x=idseg[i]; is[x]=1; vis[x]=0; } cnt=cp=cl=cr=0; for(i=1;i<=cs;i++){ x=idseg[i]; if(vis[x])continue; cnt++; com[cnt].st=cp+1; com[cnt].isl=com[cnt].isr=0; vis[x]=1; int head=1,tail=1; q[1]=x; while(head<=tail){ x=q[head++]; const Line&p=seg[x]; if(p.xl>xl&&p.xr<xr){ pool[++cp]=p.a; pool[++cp]=p.b; }else if(p.xr<xr){ if(p.xl==p.xr){ com[cnt].upl(Frac(p.a.y,1)); com[cnt].upl(Frac(p.b.y,1)); }else{ pool[++cp]=p.b; com[cnt].upl(gety(p,xl)); } }else{ if(p.xl==p.xr){ com[cnt].upr(Frac(p.a.y,1)); com[cnt].upr(Frac(p.b.y,1)); }else{ pool[++cp]=p.a; com[cnt].upr(gety(p,xr)); } } for(j=x-1;j<=x+1;j+=2){ k=j; if(k<0)k+=n; if(k>=n)k-=n; if(!is[k]||vis[k])continue; const P&v=j<x?a[x]:a[x+1]; if(v.x<xl||v.x>xr)continue; vis[k]=1; q[++tail]=k; } } com[cnt].en=cp; if(com[cnt].isl)idl[++cl]=cnt; if(com[cnt].isr)idr[++cr]=cnt; sort(pool+com[cnt].st,pool+cp+1,cmpx); } for(i=1;i<=cs;i++)is[idseg[i]]=0; CaseLeft::solve(); CaseRight::solve(); } } void solve(int o,int l,int r,int cs,int cq){ if(l>=r||!cs||!cq)return; //Case 1: whole seg CaseWholeSeg::init(); CaseWholeQue::init(l,r); for(int i=0;i<cs;i++){ int id=idseg[o][i]; int a=seg[id].xl,b=seg[id].xr; if(a<=l&&b>=r)CaseWholeSeg::add(id); else CaseWholeQue::addseg(id); } CaseWholeSeg::work(); for(int i=0;i<cq;i++){ int id=idque[o][i]; int a=que[id].xl,b=que[id].xr; if(CaseWholeSeg::ask(que[id]))ans[id]=1; else if(a<=l&&b>=r)CaseWholeQue::addque(id); } //Case 2: whole query, partial seg CaseWholeQue::work(); if(l+1==r)return; int mid=(l+r)>>1; for(int _=0;_<2;_++){ int _l,_r,_cs=0,_cq=0; if(_==0)_l=l,_r=mid;else _l=mid,_r=r; for(int i=0;i<cs;i++){ int id=idseg[o][i]; int a=seg[id].xl,b=seg[id].xr; if(a<=l&&b>=r)continue; if(a>_r||b<_l)continue; idseg[o+1][_cs++]=id; } for(int i=0;i<cq;i++){ int id=idque[o][i]; if(ans[id])continue; int a=que[id].xl,b=que[id].xr; if(a<=l&&b>=r)continue; if(a>_r||b<_l)continue; idque[o+1][_cq++]=id; } solve(o+1,_l,_r,_cs,_cq); } } namespace CaseBothSameX{ int i,l,r,x,ce; struct E{ int x,y,v,p; E(){} E(int _x,int _y,int _v,int _p){x=_x,y=_y,v=_v,p=_p;} }e[N+M]; inline bool cmpe(const E&a,const E&b){ if(a.x!=b.x)return a.x<b.x; if(a.y!=b.y)return a.y<b.y; return a.p<b.p; } void solve(){ for(i=0;i<cq;i++){ x=idque[0][i]; if(ans[x])continue; if(que[x].xl!=que[x].xr)continue; l=que[x].a.y,r=que[x].b.y; if(l>r)swap(l,r); e[ce++]=E(que[x].xl,r,l,x); } for(i=0;i<n;i++)if(a[i].x==a[i+1].x){ l=a[i].y,r=a[i+1].y; if(l>r)swap(l,r); e[ce++]=E(a[i].x,l,r,-1); } sort(e,e+ce,cmpe); for(i=0;i<ce;i++){ if(i==0||e[i].x!=e[i-1].x)r=-inf; if(e[i].p<0)umax(r,e[i].v); else if(r>=e[i].v)ans[e[i].p]=1; } } } int main(){ scanf("%d%d",&n,&m); xl=inf,xr=-inf; for(i=0;i<n;i++){ a[i].read(); umin(xl,a[i].x); umax(xr,a[i].x); } a[n]=a[0]; for(i=0;i<n;i++){ seg[i].a=a[i]; seg[i].b=a[i+1]; seg[i].fix(); idseg[0][i]=i; } for(i=0;i<m;i++){ que[i].a.read(); que[i].b.read(); que[i].fix(); umax(que[i].xl,xl); umin(que[i].xr,xr); if(que[i].xl>que[i].xr)continue; if(que[i].xl==que[i].xr&&que[i].a.x!=que[i].b.x){ if(que[i].xl==xl)que[i].a=que[i].b; else que[i].b=que[i].a; que[i].fix(); } idque[0][cq++]=i; if(que[i].xl<que[i].xr)slo[i]=Frac(que[i].b.y-que[i].a.y,que[i].b.x-que[i].a.x); } solve(0,xl,xr,n,cq); CaseBothSameX::solve(); for(i=0;i<m;i++)puts(ans[i]?"YES":"NO"); }
C. Shuttle Tour
#include<cstdio> typedef long long ll; const int N=200005,K=55; char on[N]; int n,m,i,op,x,y,z,g[N],v[N<<1],w[N<<1],nxt[N<<1],ed,seg[N]; int at[N],pool[N],pos[N],cp; int cnt,pre[K],len[K],cross[K],start[K]; ll sum[N]; inline void umin(int&a,int b){a>b?(a=b):0;} inline void umax(int&a,int b){a<b?(a=b):0;} struct E{ int l[K],r[K];bool have; void clr(){ for(int i=1;i<=cnt;i++){ l[i]=N; r[i]=0; } have=0; } void init(int x,int o){ clr(); if(o){ l[at[x]]=r[at[x]]=pos[x]; have=1; } } void operator+=(const E&o){ for(int i=1;i<=cnt;i++){ umin(l[i],o.l[i]); umax(r[i],o.r[i]); } have|=o.have; } ll cal(){ if(!have)return -1; static int sub[K]; int i,j,k; ll ret=0; for(i=1;i<=cnt;i++){ sub[i]=l[i]<=r[i]; } for(i=cnt;i;i--)sub[pre[i]]+=sub[i]; for(i=cnt;i;i--){ j=pre[i],k=cross[i]; if(sub[i]&&sub[i]<sub[1]){ umin(l[j],k); umax(r[j],k); ret+=len[i]; umin(l[i],start[i]); umax(r[i],start[i]); } if(l[i]<r[i])ret+=sum[pool[r[i]]]-sum[pool[l[i]]]; } return ret*2; } }val[524305],ans; inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;} void dfs(int x,int y,int z){ pool[++cp]=x; pos[x]=cp; at[x]=z; bool first=1; for(int i=g[x];i;i=nxt[i]){ int u=v[i]; if(u==y)continue; sum[u]=sum[x]+w[i]; if(first){ dfs(u,x,z); first=0; }else{ cnt++; pre[cnt]=z; len[cnt]=w[i]; cross[cnt]=pos[x]; start[cnt]=cp+1; dfs(u,x,cnt); } } } inline void up(int x){ val[x]=val[x<<1]; val[x]+=val[x<<1|1]; } void build(int x,int a,int b){ if(a==b){ seg[a]=x; val[x].init(a,on[a]); return; } int mid=(a+b)>>1; build(x<<1,a,mid); build(x<<1|1,mid+1,b); up(x); } inline void change(int x){ int y=seg[x]; val[y].init(x,on[x]); for(y>>=1;y;y>>=1)up(y); } void ask(int x,int a,int b,int c,int d){ if(c<=a&&b<=d){ ans+=val[x]; return; } int mid=(a+b)>>1; if(c<=mid)ask(x<<1,a,mid,c,d); if(d>mid)ask(x<<1|1,mid+1,b,c,d); } int main(){ scanf("%d%d%s",&n,&m,on+1); for(i=1;i<=n;i++)on[i]-='0'; for(i=1;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z); cnt=1; dfs(1,0,1); build(1,1,n); while(m--){ scanf("%d%d",&op,&x); if(op==1){ on[x]^=1; change(x); }else{ scanf("%d",&y); ans.clr(); ask(1,1,n,x,y); printf("%lld\n",ans.cal()); } } }
D. Master of Both III
#include<bits/stdc++.h> using namespace std; const int N=22,P=998244353; int n,w[N]; long long f[1<<N]; void cmin(long long &a,long long b) { a=a<b?a:b; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&w[i]); reverse(w+1,w+n); for(int S=0;S<(1<<n);S++) f[S]=1e18; f[0]=f[1]=0; int A=(1<<n)-1; for(long long S=1;S<(1<<n);S++) for(int i=1;i<n;i++) cmin(f[S|((S<<i)&A)|((S<<i)>>n)],f[S]+w[i]); for(int S=A;S>=0;S--) for(int i=0;i<n;i++) if(!(S>>i&1)) cmin(f[S],f[S^(1<<i)]); long long ans=0; for(int S=0;S<(1<<n);S++) { ans+=f[S]*S; ans%=P; } printf("%lld\n",ans); }
E. Interval Sum
#include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); int n; cin>>n; if(n%2==0) { cout<<n/2<<' '; } cout<<n<<' '; for(int i=1;i<=(n-1)/2;i++) cout<<i<<' '<<n-i<<' '; cout<<endl; return 0; }
F. Turn on the Light
#include<bits/stdc++.h> using namespace std; const int N=33; int n; void solve(int l,int r,int cl,int cr) { if(l==r) { printf("! %d\n",l); fflush(stdout); // exit(0); return; } if(r==l+1) { printf("? %d\n",l); fflush(stdout); int x; scanf("%d",&x); if(x==abs(cl-cr)) solve(l,l,cl,cr); else solve(r,r,cl+1,cr); return; } if(cl==cr) { printf("? %d\n",r); fflush(stdout); int x; scanf("%d",&x); if(x==abs(cl-cr)) solve(r,r,cl,cr); else solve(l,r-1,cl,cr+1); } else { int mid=(l+r)>>1; printf("? %d\n",mid); fflush(stdout); int x; scanf("%d",&x); if(x==abs(cl-cr)) solve(mid,mid,cl,cr); else if(x==abs(cl-(cr+1))) solve(l,mid-1,cl,cr+1); else solve(mid+1,r,cl+1,cr); } } int main() { scanf("%d",&n); solve(1,n,0,0 ); }
G. Puzzle: Kusabi
#include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); int n; cin>>n; vector<int> pa(n+5),dep(n+5); vector<int> ty(n+5); dep[1]=1; for(int i=2;i<=n;i++) { int u,v; string s; cin>>u>>v>>s; if(s=="Chang")ty[i]=3; else if(s=="Tong")ty[i]=2; else if(s=="Duan")ty[i]=1; pa[i]=v; dep[i]=dep[v]+1; } vector<pair<int,int>> ans; vector<vector<tuple<int,int,int>>> rem(n+5); for(int u=n;u>=1;u--) { if(ty[u])rem[u].emplace_back(u,ty[u],dep[u]); vector<pair<int,int>> spl[5]; // cerr<<"merge "<<u<<endl; for(auto [id,t,d]:rem[u]) { // cerr<<id<<' '<<t<<' '<<d<<endl; spl[t].emplace_back(d,id); } for(int i=1;i<=3;i++)sort(spl[i].begin(),spl[i].end()); int fl=0; while(not spl[2].empty()) { auto [d1,x]=spl[2].back();spl[2].pop_back(); if(spl[2].empty()) { if(fl)return cout<<"NO"<<endl,0; rem[pa[u]].emplace_back(x,2,d1); fl=1; break; } auto [d2,y]=spl[2].back();spl[2].pop_back(); if(d1!=d2) { if(fl or spl[2].empty())return cout<<"NO"<<endl,0; rem[pa[u]].emplace_back(x,2,d1); fl=1; tie(d1,x)=spl[2].back();spl[2].pop_back(); } if(d1!=d2)return cout<<"NO"<<endl,0; ans.emplace_back(x,y); } if(spl[1].size()!=spl[3].size() and fl)return cout<<"NO"<<endl,0; if(spl[1].size()==spl[3].size()) { for(int i=0;i<(int)spl[1].size();i++) { if(spl[1][i].first<spl[3][i].first)ans.emplace_back(spl[1][i].second,spl[3][i].second); else return cout<<"NO"<<endl,0; } } else if(spl[1].size()>spl[3].size())//keep shortest in 1 { if((int)spl[1].size()>(int)spl[3].size()+1)return cout<<"NO"<<endl,0; for(int i=spl[3].size()-1,j=spl[1].size()-1;i>=0;i--,j--) { if(spl[1][j].first<spl[3][i].first)ans.emplace_back(spl[1][j].second,spl[3][i].second); else { if(fl)return cout<<"NO"<<endl,0; else rem[pa[u]].emplace_back(spl[1][j].second,1,spl[1][j].first),fl=1,i++; } } if(not fl)rem[pa[u]].emplace_back(spl[1][0].second,1,spl[1][0].first); } else //keep longest in 3 { if((int)spl[3].size()>(int)spl[1].size()+1)return cout<<"NO"<<endl,0; for(int i=0,j=0;i<(int)spl[1].size();i++,j++) { if(spl[1][i].first<spl[3][j].first)ans.emplace_back(spl[1][i].second,spl[3][j].second); else { if(fl)return cout<<"NO"<<endl,0; else rem[pa[u]].emplace_back(spl[3][j].second,3,spl[3][j].first),fl=1,i--; } } if(not fl)rem[pa[u]].emplace_back(spl[3][spl[3].size()-1].second,3,spl[3][spl[3].size()-1].first); } } if(not rem[0].empty())return cout<<"NO"<<endl,0; cout<<"YES"<<endl; for(auto [x,y]:ans)cout<<x<<' '<<y<<endl; return 0; }
H. Puzzle: Tapa
#include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); int n,m; cin>>n>>m; vector<string> S(2*n+5); for(int i=1;i<=2*n-1;i++) { string s; cin>>s; S[i]=' '+s; for(int j=1;j<=2*m-1;j++) if(S[i][j]=='.') S[i][j]='#'; } vector<vector<int>> G(n*m+5); auto getty=[&](int x,int y){return (x==1 or x==n) or (y==1 or y==m);}; auto geths=[&](int x,int y){return (x-1)*m+y;}; auto addedge=[&](int u,int v){G[u].push_back(v);G[v].push_back(u);}; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(S[2*i-1][2*j-1]=='2' or S[2*i-1][2*j-1]=='4' or S[2*i-1][2*j-1]=='7') { if(j<m) { if(m==2 and i!=1 and i!=n){} else if(S[2*i-1][2*j+1]=='2' or S[2*i-1][2*j+1]=='4' or S[2*i-1][2*j+1]=='7') if(getty(i,j)==getty(i,j+1)) addedge(geths(i,j),geths(i,j+1)); } if(i<n) { if(n==2 and j!=1 and j!=m){} else if(S[2*i+1][2*j-1]=='2' or S[2*i+1][2*j-1]=='4' or S[2*i+1][2*j-1]=='7') if(getty(i,j)==getty(i+1,j)) addedge(geths(i,j),geths(i+1,j)); } } } vector<int> ma(n*m+5); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if((i+j)%2==0 and (S[2*i-1][2*j-1]=='2' or S[2*i-1][2*j-1]=='4' or S[2*i-1][2*j-1]=='7')) { int u=geths(i,j); for(auto v:G[u]) { if(!ma[v]) { // cerr<<"match "<<u<<' '<<v<<endl; ma[u]=v,ma[v]=u; break; } } } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if((i+j)%2==0 and (S[2*i-1][2*j-1]=='2' or S[2*i-1][2*j-1]=='4' or S[2*i-1][2*j-1]=='7')) { int u=geths(i,j); if(!ma[u]) { vector<int> vis(n*m+5); function<bool(int)> dfs=[&](int u) { // cerr<<"dfs "<<u<<endl; for(auto v:G[u]) { if(not vis[v]) { vis[v]=1; if(!ma[v] or dfs(ma[v])) { // cerr<<"match "<<u<<' '<<v<<endl; ma[u]=v,ma[v]=u; return true; } } } return false; }; if(not dfs(u)) { cout<<"NO"<<endl; return 0; } } } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if((S[2*i-1][2*j-1]=='2' or S[2*i-1][2*j-1]=='4' or S[2*i-1][2*j-1]=='7') and not ma[geths(i,j)]) { cout<<"NO"<<endl; return 0; } if(ma[geths(i,j)]) { int v=ma[geths(i,j)]; int x=(v-1)/m+1,y=(v-1)%m+1; if(x>i)S[2*i-1+1][2*j-1]='.'; else if(y>j)S[2*i-1][2*j-1+1]='.'; } } cout<<"YES"<<endl; for(int i=1;i<=2*n-1;i++) { for(int j=1;j<=2*m-1;j++) cout<<S[i][j]; cout<<endl; } return 0; }
I. Equation Discovering
#include <bits/stdc++.h> using namespace std; inline void TestComplexity() { int n = 11; int unary = 2; int binary = 4; int ter = 1; int f[20][20]; memset(f, 0, sizeof f); f[0][0] = 1; for (int i = 0; i < n; ++i) for (int j = 0; j <= i; ++j) { f[i + 1][j + 1] += f[i][j] * ter; if (j >= 1) f[i + 1][j] += f[i][j] * unary; if (j >= 2) f[i + 1][j - 1] += f[i][j] * binary; } printf("%d\n", f[n][1]); // 2240512 // time complexity = 2240512 * 20 = 4e7 } const int N = 20; int n; double dx[N], dy[N]; struct StackItem { int size; double a[N]; }; StackItem operator+(const StackItem &u, const StackItem &v) { StackItem ans; ans.size = u.size + v.size; for (int i = 0; i < n; ++i) ans.a[i] = u.a[i] + v.a[i]; return ans; } StackItem operator-(const StackItem &u, const StackItem &v) { StackItem ans; ans.size = u.size + v.size; for (int i = 0; i < n; ++i) ans.a[i] = u.a[i] - v.a[i]; return ans; } StackItem operator*(const StackItem &u, const StackItem &v) { StackItem ans; ans.size = u.size + v.size; for (int i = 0; i < n; ++i) ans.a[i] = u.a[i] * v.a[i]; return ans; } StackItem operator/(const StackItem &u, const StackItem &v) { StackItem ans; ans.size = u.size + v.size; for (int i = 0; i < n; ++i) ans.a[i] = u.a[i] / v.a[i]; return ans; } StackItem Sin(StackItem u) { for (int i = 0; i < n; ++i) u.a[i] = sin(u.a[i]); return u; } StackItem Cos(StackItem u) { for (int i = 0; i < n; ++i) u.a[i] = cos(u.a[i]); return u; } StackItem MakeX() { StackItem ans; ans.size = 1; for (int i = 0; i < n; ++i) ans.a[i] = dx[i]; return ans; } bool Test(const StackItem &u) { for (int i = 0; i < n; ++i) if (abs(u.a[i] - dy[i]) / max(1.0, abs(dy[i])) > 1e-3) return 0; return 1; } bool TestDiv(const StackItem &u) { for (int i = 0; i < n; ++i) if (abs(u.a[i]) < 0.02) return 0; return 1; } StackItem sta[N], backup[N][2]; char sol[N]; namespace PrintOut { int c[N][2], sta[N]; void Print(char *sol, int x) { if (sol[x] == 'x') { printf("x"); } else if (sol[x] == 'c') { printf("cos("); Print(sol, c[x][0]); printf(")"); } else if (sol[x] == 's') { printf("sin("); Print(sol, c[x][0]); printf(")"); } else if (sol[x] == '+' || sol[x] == '-' || sol[x] == '*' || sol[x] == '/') { printf("("); Print(sol, c[x][0]); printf("%c", sol[x]); Print(sol, c[x][1]); printf(")"); } } void Solve(char *sol) { int top = 0; for (int i = 0; sol[i]; ++i) { if (sol[i] == '+' || sol[i] == '-' || sol[i] == '*' || sol[i] == '/') { c[i][0] = sta[top - 2]; c[i][1] = sta[top - 1]; top -= 2; } else if (sol[i] == 'c' || sol[i] == 's') { c[i][0] = sta[top - 1]; top -= 1; } sta[top++] = i; } Print(sol, sta[top - 1]); puts(""); } } inline void Dfs(int ps, int top) { if (top == 1 && Test(sta[top - 1])) { sol[ps] = 0; PrintOut::Solve(sol); exit(0); } if (ps == 10) return; if (top + 1 - (10 - ps - 1) <= 1) { sol[ps] = 'x'; sta[top] = MakeX(); Dfs(ps + 1, top + 1); } if (top - (10 - ps - 1) <= 1 && top) { backup[ps][0] = sta[top - 1]; sol[ps] = 'c'; sta[top - 1] = Cos(backup[ps][0]); Dfs(ps + 1, top); sol[ps] = 's'; sta[top - 1] = Sin(backup[ps][0]); Dfs(ps + 1, top); sta[top - 1] = backup[ps][0]; } if (top >= 2) { backup[ps][0] = sta[top - 2]; backup[ps][1] = sta[top - 1]; if (backup[ps][0].size <= backup[ps][1].size) { sol[ps] = '+'; sta[top - 2] = backup[ps][0] + backup[ps][1]; Dfs(ps + 1, top - 1); sol[ps] = '*'; sta[top - 2] = backup[ps][0] * backup[ps][1]; Dfs(ps + 1, top - 1); } sol[ps] = '-'; sta[top - 2] = backup[ps][0] - backup[ps][1]; Dfs(ps + 1, top - 1); if (TestDiv(backup[ps][1])) { sol[ps] = '/'; sta[top - 2] = backup[ps][0] / backup[ps][1]; Dfs(ps + 1, top - 1); } sta[top - 2] = backup[ps][0]; sta[top - 1] = backup[ps][1]; } } int main() { scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%lf%lf", dx + i, dy + i); } Dfs(0, 0); return 0; }
J. Stage Clear
#include<cstdio> #include<algorithm> #include<queue> using namespace std; typedef long long ll; const int N=47,LIM=26; const ll inf=1LL<<60; int n,m,i,x,y,deg[N],pre[N][N];ll ans=inf; struct P{ ll a,b; P(){} P(ll _a,ll _b){a=_a,b=_b;} bool operator<(const P&o)const{ int sgn1=a<b,sgn2=o.a<o.b; if(sgn1!=sgn2)return sgn1<sgn2; if(a<b)return a>o.a; return b<o.b; } void operator+=(const P&o){ ll na=max(a,a-b+o.a),nb=b+o.b-a-o.a+na; a=na,b=nb; } }a[N],init[N]; inline void up(ll&a,ll b){a>b?(a=b):0;} namespace SMALL{ int m,S,i,j,k,mask[N];ll va[N],vb[N],f[(1<<(LIM-1))+1]; void solve(){ for(i=2;i<=n;i++){ S=0; for(j=0;j<deg[i];j++){ k=pre[i][j]; if(k>1)S|=1<<(k-2);else S|=1<<n; } mask[i-2]=S; va[i-2]=a[i].a; vb[i-2]=a[i].b; } n--; m=1<<n; for(S=1;S<m;S++)f[S]=inf; for(S=0;S<m;S++){ ll tmp=f[S]; if(tmp>=inf)continue; for(i=0;i<n;i++)if(!(S>>i&1)){ if((mask[i]&S)==mask[i])continue; ll now=tmp; now-=vb[i]; if(now<0)now=0; now+=va[i]; up(f[S^(1<<i)],now); } } ans=f[m-1]; } } namespace BIG{ int fa[N],f[N],vis[N],del[N],pos; typedef pair<int,int>PI; typedef pair<P,PI>PII; priority_queue<PII>q; int F(int x){return del[f[x]]?f[x]=F(f[x]):f[x];} inline void solve_tree(){ int i,x,y; for(pos=i=0;i<=n;i++)vis[i]=del[i]=0; a[1]=P(0,0); for(i=2;i<=n;i++)a[i]=init[i],f[i]=fa[i]; for(i=2;i<=n;i++)q.push(PII(a[i],PI(0,i))); while(!q.empty()){ PII t=q.top(); q.pop(); x=t.second.second; if(del[x])continue; if(t.second.first!=vis[x])continue; del[x]=1; y=F(x); a[y]+=a[x]; if(y>1)q.push(PII(a[y],PI(vis[y]=++pos,y))); } up(ans,a[1].a); } void dfs(int x){ if(x>n){ solve_tree(); return; } for(int i=0;i<deg[x];i++){ fa[x]=pre[x][i]; dfs(x+1); } } void solve(){ for(i=1;i<=n;i++)init[i]=a[i]; dfs(2); } } int main(){ scanf("%d%d",&n,&m); for(i=2;i<=n;i++)scanf("%lld%lld",&a[i].a,&a[i].b); while(m--){ scanf("%d%d",&x,&y); pre[y][deg[y]++]=x; } if(n<=LIM)SMALL::solve();else BIG::solve(); printf("%lld",ans); }
K. Lazy but Diligent
#include<bits/stdc++.h> using namespace std; #define N 420 struct course{ int s,t,p; bool operator < (const course &c) const{ return s<c.s; } }a[N]; int n,m,q,s,t,f[N][N],dp[N][N]; void cmin(int &x,int y){x=min(x,y);} void cmax(int &x,int y){x=max(x,y);} int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>m>>q>>t>>s; memset(f,0x3f,sizeof f); for (int i=1;i<=n;++i) f[i][i]=0; for (int i=1;i<=m;++i){ int x,y,z; cin>>x>>y>>z; cmin(f[x][y],z); cmin(f[y][x],z); } for (int k=1;k<=n;++k){ for (int i=1;i<=n;++i){ for (int j=1;j<=n;++j){ cmin(f[i][j],f[i][k]+f[k][j]); } } } for (int i=1;i<=q;++i){ cin>>a[i].s>>a[i].t>>a[i].p; } a[0].s=a[0].t=0; a[0].p=1; ++q; a[q].s=a[q].t=t; a[q].p=1; sort(a,a+q+1); memset(dp,0xcf,sizeof dp); dp[0][0]=0; for (int i=1;i<=q;++i){ for (int j=1;j<=i;++j){ for (int k=0;k<i;++k){ int ti=a[i].s-a[k].t; int x=a[i].p,y=a[k].p; if (f[x][y]<=ti) cmax(dp[i][j],dp[k][j-1]); if (int dlt=ti-f[1][x]-f[1][y];dlt>=0) cmax(dp[i][j],dp[k][j-1]+dlt); } } } int ans=0; for (int i=1;i<=q;++i) if (dp[q][i]>=s) ans=i; cout<<ans-1<<'\n'; }
L. Barkley
#include<bits/stdc++.h> using namespace std; using ll=long long; using pii=pair<ll,int>; #define fs first #define sd second #define mp make_pair const int N=1e5+1e3+7; int n,q; ll a[N]; vector<pii>g[N]; ll ans; void dfs(int x,ll G,int t,int k) { if(x<t) { ans=max(ans,G); return; } if(!k) { for(auto [w,p]:g[x]) if(p<=t) { ans=max(ans,__gcd(G,w)); break; } return; } dfs(x-1,G,t,k-1); for(auto [w,p]:g[x]) dfs(p-2,__gcd(G,w),t,k-1); } int main() { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) { vector<pii>ng=g[i-1]; for(auto &[x,y]:ng) x=__gcd(x,a[i]); ng.push_back({a[i],i}); for(auto [x,y]:ng) if(!g[i].size()||x!=g[i].back().fs) g[i].push_back({x,y}); } for(int i=1;i<=n;i++) reverse(g[i].begin(),g[i].end()); while(q--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); ans=0; dfs(r,0,l,k); printf("%lld\n",ans); } }
M. A Wine and Four Dishes
#include<bits/stdc++.h> using namespace std; const int N=33; int n,x,y; int a[N],b[N]; int main() { scanf("%d%d%d",&n,&x,&y); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); if(!x&&!y) { puts("0"); return 0; } int ans=0; if(x) { int mx=-1; for(int i=1;i<=n;i++) if(a[i]==1) mx=max(mx,b[i]); if(mx==-1) { puts("IMPOSSIBLE"); return 0; } for(int i=1;i<=n;i++) if(a[i]==1&&b[i]==mx) { y-=b[i]; b[i]=0; break; } ans++; } sort(b+1,b+n+1); for(int i=n;i>=1;i--) { if(y<=0) break; ans++; y-=b[i]; } if(y>0) puts("IMPOSSIBLE"); else printf("%d\n",ans); }