The 13th Chinese Northeast Collegiate Programming Contest
题解:
Code:
A. Apple Business
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int N=100010; int Case,len[N],n,m,i,mx,a[N],size[N],tmp[N];ll ans; vector<ll>v[N],f[N]; struct E{int u,v,c,w;}e[N]; inline bool cmp(const E&a,const E&b){return a.w>b.w;} void dfs(int x,int y){ if(x>n)return; if(y>mx)mx=y; tmp[y]=a[x]; dfs(x<<1,y<<1); dfs(x<<1|1,y<<1|1); } inline void init(int o){ mx=0; dfs(o,1); size[o]=mx; v[o].resize(mx+1); f[o].resize(mx+1); for(int i=1;i<=mx;i++)v[o][i]=f[o][i]=tmp[i]; } inline int getid(int x,int y){ int k=1<<(len[y]-len[x]); return (y&(k-1))|k; } inline void append(int A,int B,int C,int W){ int x,y,o,t,m; for(x=A;x;x>>=1){ o=getid(x,B); m=size[x]; ll dp=f[x][o]; for(y=o>>1;y;o=y,y>>=1){ dp+=v[x][y]; t=y<<1; if(t<=m&&t!=o&&f[x][t]<0)dp+=f[x][t]; t=y<<1|1; if(t<=m&&t!=o&&f[x][t]<0)dp+=f[x][t]; } if(dp<C)C=dp; } if(!C)return; ans+=1LL*C*W; for(x=A;x;x>>=1){ o=getid(x,B); m=size[x]; v[x][o]-=C; f[x][o]-=C; for(y=o>>1;y;y>>=1){ f[x][y]=v[x][y]; t=y<<1; if(t<=m&&f[x][t]<0)f[x][y]+=f[x][t]; t=y<<1|1; if(t<=m&&f[x][t]<0)f[x][y]+=f[x][t]; } } } int main(){ for(i=1;i<N;i++)len[i]=len[i>>1]+1; scanf("%d",&Case); while(Case--){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%d",&a[i]); for(i=1;i<=n;i++)init(i); for(i=1;i<=m;i++)scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].c,&e[i].w); sort(e+1,e+m+1,cmp); ans=0; for(i=1;i<=m;i++)append(e[i].u,e[i].v,e[i].c,e[i].w); printf("%lld\n",ans); } }
B. Balanced Diet
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=100010; int T,n,m,i,j,k,l[N];ll f[N],s,A,B,d; struct E{int a,b;}e[N]; inline bool cmp(const E&a,const E&b){return a.b==b.b?a.a>b.a:a.b<b.b;} ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(i=1;i<=m;i++)scanf("%d",&l[i]); for(i=1;i<=n;i++)scanf("%d%d",&e[i].a,&e[i].b); sort(e+1,e+n+1,cmp); for(i=1;i<=n;i++)f[i]=0; for(i=1;i<=n;i=j){ for(j=i;j<=n&&e[i].b==e[j].b;j++); s=0; for(k=i;k<j;k++){ s+=e[k].a; if(k-i+1==l[e[i].b])f[k-i+1]+=s; if(k-i+1>l[e[i].b])f[k-i+1]+=e[k].a; } } for(i=1;i<=n;i++)f[i]+=f[i-1]; A=f[1],B=1; for(i=2;i<=n;i++)if(f[i]*B>A*i)A=f[i],B=i; d=gcd(A,B); printf("%lld/%lld\n",A/d,B/d); } }
C. Line-line Intersection
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=100010; int Case,n,i;pair<ll,pair<ll,ll> >f[N],g[N]; inline ll myabs(ll x){return x>0?x:-x;} ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll cal(pair<ll,pair<ll,ll> >f[]){ int i,j; ll ret=0; sort(f+1,f+n+1); for(i=1;i<=n;i=j){ for(j=i;j<=n&&f[i]==f[j];j++); ret+=1LL*(j-i)*(j-i-1); } return ret/2; } int main(){ scanf("%d",&Case); while(Case--){ scanf("%d",&n); for(i=1;i<=n;i++){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int dx=x2-x1,dy=y2-y1; ll a,b,c; if(dx==0){ a=1; b=0; c=-x1; }else{ a=-dy; b=dx; c=1LL*dy*x1-1LL*dx*y1; } if(a<0)a=-a,b=-b,c=-c; if(a==0&&b<0)b=-b,c=-c; ll d=gcd(myabs(a),gcd(myabs(b),myabs(c))); a/=d,b/=d,c/=d; f[i].first=a,f[i].second.first=b,f[i].second.second=c; d=gcd(myabs(a),myabs(b)); a/=d,b/=d; g[i].first=a,g[i].second.first=b,g[i].second.second=0; } printf("%lld\n",1LL*n*(n-1)/2-cal(g)+cal(f)); } }
D. Master of Data Structure
#include<cstdio> #include<cstring> #include<cstdlib> const int N=500010,M=2010,K=M*4,inf=~0U>>1; int Case,n,m,i,o,x,y,z,root,op[M][4]; int vip[N],g[N],v[N<<1],nxt[N<<1],ed,f[N],d[N],id[N],cnt; int at[K],G[K],W[K],NXT[K],F[K],D[K]; int vv[K],ve[K]; inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void addedge(int x,int y,int z){NXT[y]=G[x];G[x]=y;W[y]=z;} 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 int abs(int x){return x>0?x:-x;} inline void swap(int&a,int&b){int c=a;a=b;b=c;} void dfs(int x){ int deg=0; for(int i=g[x];i;i=nxt[i]){ int u=v[i]; if(u==f[x])continue; f[u]=x; d[u]=d[x]+1; dfs(u); if(!id[u])continue; deg++; id[x]^=id[u]; } if(deg>1)vip[x]=1; if(!vip[x])return; id[x]=++cnt; at[cnt]=x; for(int i=g[x];i;i=nxt[i]){ int u=v[i]; if(u==f[x])continue; u=id[u]; if(!u)continue; addedge(cnt,u,d[at[u]]-d[x]-1); } } void dfs2(int x,int y){ F[x]=y; D[x]=D[y]+1; for(int i=G[x];i;i=NXT[i])dfs2(i,x); } int main(){ scanf("%d",&Case); while(Case--){ scanf("%d%d",&n,&m); for(ed=cnt=i=0;i<=n;i++)f[i]=d[i]=id[i]=vip[i]=g[i]=0; memset(G,0,sizeof G); memset(W,0,sizeof W); memset(F,0,sizeof F); memset(D,0,sizeof D); memset(vv,0,sizeof vv); memset(ve,0,sizeof ve); for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x); for(i=1;i<=m;i++){ scanf("%d%d%d",&o,&x,&y); vip[x]=vip[y]=1; op[i][0]=o; op[i][1]=x; op[i][2]=y; if(o==1||o==2||o==3||o==7)scanf("%d",&op[i][3]); } for(i=1;i<=n;i++)if(vip[i])root=i; dfs(root); dfs2(id[root],0); for(i=1;i<=m;i++){ o=op[i][0]; x=id[op[i][1]]; y=id[op[i][2]]; z=op[i][3]; if(o==1){ while(x!=y){ if(D[x]<D[y])swap(x,y); vv[x]+=z; ve[x]+=z; x=F[x]; } vv[x]+=z; } if(o==2){ while(x!=y){ if(D[x]<D[y])swap(x,y); vv[x]^=z; ve[x]^=z; x=F[x]; } vv[x]^=z; } if(o==3){ while(x!=y){ if(D[x]<D[y])swap(x,y); if(vv[x]>=z)vv[x]-=z; if(ve[x]>=z)ve[x]-=z; x=F[x]; } if(vv[x]>=z)vv[x]-=z; } if(o==4){ long long ans=0; while(x!=y){ if(D[x]<D[y])swap(x,y); ans+=vv[x]; ans+=1LL*ve[x]*W[x]; x=F[x]; } printf("%lld\n",ans+vv[x]); } if(o==5){ int ans=0; while(x!=y){ if(D[x]<D[y])swap(x,y); ans^=vv[x]; if(W[x]&1)ans^=ve[x]; x=F[x]; } printf("%d\n",ans^vv[x]); } if(o==6){ int mi=inf,ma=0; while(x!=y){ if(D[x]<D[y])swap(x,y); umin(mi,vv[x]); umax(ma,vv[x]); if(W[x]){ umin(mi,ve[x]); umax(ma,ve[x]); } x=F[x]; } umin(mi,vv[x]); umax(ma,vv[x]); printf("%d\n",ma-mi); } if(o==7){ int ans=inf; while(x!=y){ if(D[x]<D[y])swap(x,y); umin(ans,abs(vv[x]-z)); if(W[x])umin(ans,abs(ve[x]-z)); x=F[x]; } umin(ans,abs(vv[x]-z)); printf("%d\n",ans); } } } }
E. Minimum Spanning Tree
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int N=100010; int Case,n,i,j,x,y,z;vector<int>f[N];ll ans; int main(){ scanf("%d",&Case); while(Case--){ scanf("%d",&n); for(i=1;i<=n;i++)f[i].clear(); for(i=1;i<n;i++)scanf("%d%d%d",&x,&y,&z),f[x].push_back(z),f[y].push_back(z); ans=0; for(i=1;i<=n;i++)if(f[i].size()>1){ sort(f[i].begin(),f[i].end()); for(j=1;j<f[i].size();j++)ans+=f[i][0]+f[i][j]; } printf("%lld\n",ans); } }
F. Mini-game Before Contest
#include<cstdio> const int N=100010,M=200010,K=1<<24; int Case,n,m,i,j,k,S,A,B,x,y,z,o,deg[N],g[N],v[M],nxt[M],ed; bool isactor[6],isa[6],ismin[6]; char tmp[9]; int f[N][6],w[N][6][3]; int q[K+5],h,t; inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void ext(int x,int y,int B){ int A=f[x][y]; if(A==B)return; t=(t+1)&(K-1); q[t]=(x<<7)|(y<<4)|(A<<2)|B; f[x][y]=B; } inline void check(int x,int y){ int ret; if(ismin[y]){ if(w[x][y][0])ret=0; else if(w[x][y][1])ret=1; else ret=2; }else{ if(w[x][y][2])ret=2; else if(w[x][y][1])ret=1; else ret=0; } ext(x,y,ret); } int main(){ scanf("%d",&Case); while(Case--){ scanf("%d%d",&n,&m); for(ed=i=0;i<=n;i++)deg[i]=g[i]=0; while(m--)scanf("%d%d",&x,&y),deg[x]++,add(y,x); scanf("%s",tmp); for(i=0;i<6;i++)isa[i]=tmp[i]=='A'; scanf("%s",tmp); for(i=0;i<6;i++)isactor[i]=tmp[i]=='1'; for(i=0;i<6;i++)ismin[i]=isa[i]^isactor[i]; for(i=1;i<=n;i++)for(j=0;j<6;j++){ f[i][j]=1; for(k=0;k<3;k++)w[i][j][k]=0; w[i][j][1]=deg[i]; } h=1,t=0; for(i=1;i<=n;i++)if(!deg[i])for(j=0;j<6;j++){ if(isa[j])ext(i,j,2); else ext(i,j,0); } while(h!=((t+1)&(K-1))){ S=q[h]; h=(h+1)&(K-1); x=S>>7,y=S>>4&7,A=S>>2&3,B=S&3; o=(y+5)%6; for(i=g[x];i;i=nxt[i]){ z=v[i]; w[z][o][A]--; w[z][o][B]++; check(z,o); } } for(i=1;i<=n;i++){ if(f[i][0]==0)putchar('A'); if(f[i][0]==1)putchar('D'); if(f[i][0]==2)putchar('B'); } puts(""); } }
G. Radar Scanner
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=100010; int Case,n,m,i,j,e[N<<1]; struct P{int l,r;}a[N],b[N]; inline ll solve(P*a){ m=0; ll ans=0; for(i=1;i<=n;i++){ e[++m]=a[i].l; e[++m]=a[i].r; ans-=a[i].r-a[i].l; } sort(e+1,e+m+1); for(i=1;i<=m;i++)ans+=abs(e[i]-e[n]); return ans/2; } int main(){ scanf("%d",&Case); while(Case--){ scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d%d%d%d",&a[i].l,&b[i].l,&a[i].r,&b[i].r); printf("%lld\n",solve(a)+solve(b)); } }
H. Skyscraper
#include<cstdio> typedef long long ll; const int N=100010; int Case,n,m,i,op,x,y;ll z,a[N],b[N],f[N],g[N]; inline void ins(ll*f,int x,ll p){for(;x<=n;x+=x&-x)f[x]+=p;} inline ll ask(ll*f,int x){ll t=0;for(;x;x-=x&-x)t+=f[x];return t;} int main(){ scanf("%d",&Case); while(Case--){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%lld",&a[i]); for(i=1;i<=n;i++)b[i]=a[i]-a[i-1]; for(i=1;i<=n;i++)f[i]=g[i]=0; for(i=1;i<=n;i++){ ins(f,i,b[i]); if(b[i]>0)ins(g,i,b[i]); } while(m--){ scanf("%d%d%d",&op,&x,&y); if(op==1){ y++; scanf("%lld",&z); ins(f,x,z); ins(f,y,-z); if(b[x]>0)ins(g,x,-b[x]); if(b[y]>0)ins(g,y,-b[y]); b[x]+=z; b[y]-=z; if(b[x]>0)ins(g,x,b[x]); if(b[y]>0)ins(g,y,b[y]); }else{ printf("%lld\n",ask(f,x)+ask(g,y)-ask(g,x)); } } } }
I. Temperature Survey
#include<cstdio> #include<algorithm> #include<map> using namespace std; const int N=524288,M=200010,K=18,P=998244353,G=3; typedef unsigned int uint32; typedef long long int64; typedef unsigned long long uint64; typedef uint32 word; typedef uint64 dword; typedef int sword; const int word_bits=sizeof(word)*8; word mod,Modinv,r2; struct UnsafeMod{ word x; UnsafeMod(): x(0) {} UnsafeMod(word _x): x(init(_x)) {} UnsafeMod& operator += (const UnsafeMod& rhs) { (x += rhs.x) >= mod && (x -= mod); return *this; } UnsafeMod& operator -= (const UnsafeMod& rhs) { sword(x -= rhs.x) < 0 && (x += mod); return *this; } UnsafeMod& operator *= (const UnsafeMod& rhs) { x = reduce(dword(x) * rhs.x); return *this; } UnsafeMod operator + (const UnsafeMod &rhs) const { return UnsafeMod(*this) += rhs; } UnsafeMod operator - (const UnsafeMod &rhs) const { return UnsafeMod(*this) -= rhs; } UnsafeMod operator * (const UnsafeMod &rhs) const { return UnsafeMod(*this) *= rhs; } UnsafeMod pow(uint64 e) const { UnsafeMod ret(1); for (UnsafeMod base = *this; e; e >>= 1, base *= base) { if (e & 1) ret *= base; } return ret; } word get() const { return reduce(x); } static word modulus() { return mod; } static word init(word w) { return reduce(dword(w) * r2); } static void set_mod(word m) { mod = m; Modinv = mul_inv(mod); r2 = -dword(mod) % mod; } static word reduce(dword x) { word y = word(x >> word_bits) - word((dword(word(x) * Modinv) * mod) >> word_bits); return sword(y) < 0 ? y + mod : y; } static word mul_inv(word n, int e = 6, word x = 1) { return !e ? x : mul_inv(n, e - 1, x * (2 - x * n)); } }; int Case,n,i,j,lim[M]; UnsafeMod a[M],b[M],c[M],d[M]; UnsafeMod ta[N+5],tb[N+5]; UnsafeMod g[K+1],ng[K+10],gw[N+10],ngw[N+10]; int pos[N+10],inv[N+10]; UnsafeMod fac[N+5],rev[N+5]; map<int,UnsafeMod>f[M]; struct E{int xl,xr,yl,yr;}e[M]; inline UnsafeMod C(int n,int m){return n<m?0:fac[n]*rev[m]*rev[n-m];} inline void NTT(UnsafeMod*a,int n,int t){ int j=__builtin_ctz(n)-1; for(int i=0;i<n;i++)pos[i]=pos[i>>1]>>1|((i&1)<<j); for(int i=1;i<n;i++)if(i<pos[i])std::swap(a[i],a[pos[i]]); for(int d=0;(1<<d)<n;d++){ int m=1<<d,m2=m<<1; UnsafeMod*_w=t==1?gw:ngw; _w+=m; for(int i=0;i<n;i+=m2){ UnsafeMod*w=_w; for(int j=i;j<m+i;j++,w++){ UnsafeMod t=*w*a[j+m]; a[j+m]=a[j]-t; a[j]+=t; } } } if(t==-1){ UnsafeMod j=inv[n]; for(int i=0;i<n;i++)a[i]*=j; } } void build(int l,int r,int yl){ if(l>r)return; int mid=(l+r)>>1; e[mid].xl=mid; e[mid].xr=r; e[mid].yl=yl; e[mid].yr=lim[mid]; build(l,mid-1,yl); build(mid+1,r,lim[mid]+1); } inline UnsafeMod cal(int x,int y){ UnsafeMod t=0; if(x>1)t=f[x-1][y]; if(y>1)t+=f[x][y-1]; return f[x][y]=t; } inline void work0(int n,int m,UnsafeMod*a,UnsafeMod*b){ int i,k; for(k=1;k<=(n-1)*2;k<<=1); for(i=0;i<k;i++)ta[i]=tb[i]=0; for(i=0;i<n;i++){ ta[i]=a[i]*rev[m]; tb[i]=fac[i+m]*rev[i]; } NTT(ta,k,1),NTT(tb,k,1); for(i=0;i<k;i++)ta[i]*=tb[i]; NTT(ta,k,-1); for(i=0;i<n;i++)b[i]+=ta[i]; } inline void work1(int n,int m,UnsafeMod*a,UnsafeMod*b){ int i,k; for(k=1;k<=n+n+m-2;k<<=1); for(i=0;i<k;i++)ta[i]=tb[i]=0; for(i=0;i<n;i++)ta[i]=a[i]*rev[n-i]; for(i=0;i<n+m;i++)tb[i]=fac[i]; NTT(ta,k,1),NTT(tb,k,1); for(i=0;i<k;i++)ta[i]*=tb[i]; NTT(ta,k,-1); for(i=0;i<m;i++)b[i]+=ta[i+n]*rev[i]; } inline void solve(int o){ int xl=e[o].xl,xr=e[o].xr,yl=e[o].yl,yr=e[o].yr; if(yl>yr)return; int i,j,k,ca,cb; if(xl==1){ for(i=xl;i<=xr;i++)for(j=yl;j<=yr;j++)f[i][j]=C(i+j-2,i-1); return; } cal(xl,yl); for(i=yl+1,k=0;i<=yr;i++,k++)a[k]=cal(xl,i); for(i=xl+1,k=0;i<=xr;i++,k++)b[k]=cal(i,yl); ca=yr-yl-1; cb=xr-xl-1; if(ca<=0||cb<=0){ for(i=xl;i<=xr;i++)for(j=yl;j<=yr;j++){ if(i==xl||j==yl)continue; cal(i,j); } return; } for(i=0;i<ca;i++)c[i]=b[cb]; for(i=0;i<cb;i++)d[i]=a[ca]; work0(ca,cb,a,c); work0(cb,ca,b,d); work1(ca,cb,a,d); work1(cb,ca,b,c); for(i=0;i<ca;i++)f[xr][yl+i+1]=c[i]; for(i=0;i<cb;i++)f[xl+i+1][yr]=d[i]; f[xr][yr]=c[ca-1]+d[cb-1]; } int main(){ UnsafeMod::set_mod(P); for(g[K]=((UnsafeMod)G).pow((P-1)/N),ng[K]=g[K].pow(P-2),i=K-1;~i;i--)g[i]=g[i+1]*g[i+1],ng[i]=ng[i+1]*ng[i+1]; for(i=0;i<=K;i++){ gw[1<<i]=ngw[1<<i]=1; for(j=1;j<1<<i;j++){ gw[(1<<i)+j]=gw[(1<<i)+j-1]*g[i]; ngw[(1<<i)+j]=ngw[(1<<i)+j-1]*ng[i]; } } for(inv[0]=inv[1]=1,i=2;i<=N;i++)inv[i]=1LL*(P-inv[P%i])*(P/i)%P; for(rev[0]=rev[1]=1,i=2;i<=N;i++)rev[i]=rev[i-1]*inv[i]; for(fac[0]=i=1;i<=N;i++)fac[i]=fac[i-1]*i; scanf("%d",&Case); while(Case--){ scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&lim[i]); n++; lim[n]=lim[n-1]; for(i=1;i<=n;i++)f[i].clear(); build(1,n,1); for(i=1;i<=n;i++)solve(i); printf("%u\n",f[n][lim[n]].get()); } }
J. Time Limit
#include<cstdio> #include<algorithm> using namespace std; int Case,n,i,x,ans; int main(){ scanf("%d",&Case); while(Case--){ scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&x); if(i==1)ans=x*3; else ans=max(ans,x+1); } while(ans%2)ans++; printf("%d\n",ans); } }