2025“钉耙编程”中国大学生算法设计暑期联赛(7)
题面:
https://files.cnblogs.com/files/clrs97/%E7%AC%AC7%E5%9C%BA%E9%A2%98%E9%9D%A2.pdf
题解:
https://files.cnblogs.com/files/clrs97/%E7%AC%AC7%E5%9C%BA%E9%A2%98%E8%A7%A3.pdf
Code:
A. 矩形框选
#include<iostream> #include<algorithm> #include<vector> #include<cmath> using namespace std; typedef pair<int,int>P; const int N=10005,inf=1000000000; int Case,n,s,w,h,i,x,y,z,ans,lim,at[N],st[N],en[N],val[N],mx[N],tag[N]; vector<P>f[N],g[N]; inline void up(int&a,int b){a<b?(a=b):0;} inline void add(int l,int r,int p){ int L=at[l],R=at[r],i,nmx; if(L==R){ nmx=mx[L]; for(i=l;i<=r;i++){ val[i]+=p; up(nmx,val[i]); } mx[L]=nmx; up(ans,nmx+tag[L]); return; } nmx=mx[L]; for(i=l;i<=en[L];i++){ val[i]+=p; up(nmx,val[i]); } mx[L]=nmx; up(ans,nmx+tag[L]); nmx=mx[R]; for(i=st[R];i<=r;i++){ val[i]+=p; up(nmx,val[i]); } mx[R]=nmx; up(ans,nmx+tag[R]); for(i=L+1;i<R;i++){ tag[i]+=p; up(ans,mx[i]+tag[i]); } } inline void del(int l,int r,int p){ int L=at[l],R=at[r],i,nmx; if(L==R){ for(i=l;i<=r;i++)val[i]-=p; nmx=-inf; for(i=st[L];i<=en[L];i++)up(nmx,val[i]); mx[L]=nmx; return; } for(i=l;i<=en[L];i++)val[i]-=p; nmx=-inf; for(i=st[L];i<=en[L];i++)up(nmx,val[i]); mx[L]=nmx; for(i=st[R];i<=r;i++)val[i]-=p; nmx=-inf; for(i=st[R];i<=en[R];i++)up(nmx,val[i]); mx[R]=nmx; for(i=L+1;i<R;i++)tag[i]-=p; } inline void gao(int w,int h,vector<P>f[]){ int i; lim=sqrt(h); lim=max(lim,1); for(i=1;i<=n;i++){ at[i]=(i-1)/lim; en[at[i]]=i; val[i]=0; } for(i=0;i<=at[n];i++)tag[i]=mx[i]=0; for(i=n;i;i--)st[at[i]]=i; for(i=1;i<=n;i++){ if(i>w) for(const auto&it:f[i-w]) del(it.first,min(it.first+h-1,n),it.second); for(const auto&it:f[i]) add(it.first,min(it.first+h-1,n),it.second); } } inline void solve(int w,int h){ if(w>h)gao(w,h,f); else gao(h,w,g); } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>s; for(i=1;i<=n;i++)f[i].clear(),g[i].clear(); for(i=1;i<=n;i++){ cin>>x>>y>>z; f[x].emplace_back(P(y,z)); g[y].emplace_back(P(x,z)); } ans=0; for(w=1;w<=n&&w<=s;w++){ h=min(s/w,n); w=min(s/h,n); solve(w,h); } cout<<ans<<"\n"; } }
B. 龙族栖息地
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=100005; const ll inf=1LL<<60; int Case,n;ll pool[N*2]; struct E{ll q,r,s;}e[N]; inline void umin(ll&a,ll b){a>b?(a=b):0;} inline void umax(ll&a,ll b){a<b?(a=b):0;} inline ll myabs(ll x){return x>0?x:-x;} inline ll cal(ll q){ int i; ll sum=0; for(i=1;i<=n;i++){ pool[i]=e[i].r; pool[i+n]=e[i].s-q; sum+=myabs(e[i].q-q); } nth_element(pool+1,pool+n,pool+n*2+1); ll r=pool[n]; for(i=1;i<=n*2;i++)sum+=myabs(pool[i]-r); return sum; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n; ll l=inf,r=-inf; ll minr=inf,maxr=-inf; ll mins=inf,maxs=-inf; for(int i=1;i<=n;i++){ cin>>e[i].q>>e[i].r>>e[i].s; e[i].s*=-1; umin(l,e[i].q); umax(r,e[i].q); umin(minr,e[i].r); umax(maxr,e[i].r); umin(mins,e[i].s); umax(maxs,e[i].s); } l=min(l,mins-maxr); r=max(r,maxs-minr); ll ans=inf; while(l<=r){ ll len=(r-l)/3; ll m1=l+len; ll m2=r-len; ll f1=cal(m1); ll f2=cal(m2); if(f1<f2){ umin(ans,f1); r=m2-1; }else{ umin(ans,f2); l=m1+1; } } cout<<ans/2<<"\n"; } }
C. 质疑概率
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=100005; int Case,n,k,i,a[N],b[N],sa[N],sb[N];ll v[N],q[N],lim; inline bool checkleq(){ if(lim>0)return 0; int m=1; q[1]=0; for(int i=1;i<=n;i++){ ll x=v[i]; if(x<lim||x>0)continue; if(x<=q[m]){ q[++m]=x; continue; } int l=1,r=m-1,fin=m; while(l<=r){ int mid=(l+r)>>1; if(x>q[mid])r=(fin=mid)-1;else l=mid+1; } q[fin]=x; } return m>k; } inline bool checkle(){ if(lim>=0)return 0; int m=1; q[1]=0; for(int i=1;i<=n;i++){ ll x=v[i]; if(x<lim||x>=0)continue; if(x<q[m]){ q[++m]=x; continue; } int l=1,r=m-1,fin=m; while(l<=r){ int mid=(l+r)>>1; if(x>=q[mid])r=(fin=mid)-1;else l=mid+1; } q[fin]=x; } return m>k; } inline int dir(ll u,ll d){ for(int i=1;i<=n;i++)v[i]=sb[i]*d-sa[i]*u; lim=v[n]; if(checkleq()){ if(checkle())return -1; return 0; } return 1; } inline void solve(){ ll lu=0,ld=1,ru=1,rd=1,mu,md; while(1){ mu=lu+ru; md=ld+rd; int ret=dir(mu,md); if(ret==0){ cout<<mu<<"/"<<md<<"\n"; break; } ll l=1,r,fin,mid; if(ret>0){//turn right while(1){ r=l<<1; if(dir(lu+ru*r,ld+rd*r)>0)l=r;else break; } fin=l++;r--; while(l<=r){ ll mid=(l+r)>>1; if(dir(lu+ru*mid,ld+rd*mid)>0)l=(fin=mid)+1;else r=mid-1; } lu+=ru*fin,ld+=rd*fin; }else{//turn left while(1){ r=l<<1; if(dir(ru+lu*r,rd+ld*r)<0)l=r;else break; } fin=l++;r--; while(l<=r){ ll mid=(l+r)>>1; if(dir(ru+lu*mid,rd+ld*mid)<0)l=(fin=mid)+1;else r=mid-1; } ru+=lu*fin,rd+=ld*fin; } } } inline bool check1(){ static int f[N],pre[N]; f[0]=pre[0]=0; for(int i=1,j=0;i<=n;i++){ if(a[i]!=b[i])j=i; if(j)f[i]=pre[j-1]+1;else f[i]=-N; pre[i]=max(pre[i-1],f[i]); } return f[n]>=k; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>k; for(i=1;i<=n;i++){ cin>>a[i]>>b[i]; sa[i]=sa[i-1]+a[i]; sb[i]=sb[i-1]+b[i]; } if(sb[n]==0){ cout<<"0/1\n"; continue; } if(!check1()){ cout<<"1/1\n"; continue; } solve(); } }
D. 梦醒时刻
#include<iostream> #include<algorithm> #include<vector> using namespace std; typedef pair<int,int>E; const int N=200005,M=200005,CNT=533333; int Case,n,m,i,mx[CNT],delta[CNT]; struct P{int g,k,t,l,r,d;}bomb[N]; vector<E>e[M]; void build(int x,int a,int b){ mx[x]=delta[x]=0; if(a==b)return; int mid=(a+b)>>1; build(x<<1,a,mid); build(x<<1|1,mid+1,b); } inline int ask(int x,int a,int b,int p){ int ret=0; while(1){ if(p>=mx[x])return ret; if(a==b)return ret+1; int mid=(a+b)>>1; if(p>=mx[x<<1]){ a=mid+1; x=x<<1|1; }else{ ret+=delta[x]; b=mid; x<<=1; } } } void change(int x,int a,int b,int c,int p){ if(a==b){ mx[x]^=p; return; } int mid=(a+b)>>1; if(c<=mid)change(x<<1,a,mid,c,p); else change(x<<1|1,mid+1,b,c,p); mx[x]=max(mx[x<<1],mx[x<<1|1]); delta[x]=ask(x<<1|1,mid+1,b,mx[x<<1]); } inline int kth(int p,int k){ if(ask(1,1,m,p)<k)return m+1; int x=1,a=1,b=m; while(a<b){ int mid=(a+b)>>1; x<<=1; int tmp=ask(x,a,mid,p); if(k<=tmp){ b=mid; }else{ k-=tmp; a=mid+1; p=max(p,mx[x++]); } } return a; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>m; for(i=1;i<=n;i++){ cin>>bomb[i].g>>bomb[i].k>>bomb[i].t; if(i<n)cin>>bomb[i].l>>bomb[i].r>>bomb[i].d; } build(1,1,m); for(i=1;i<=n;i++){ for(const auto&it:e[i])change(1,1,m,it.first,it.second); int t=min(kth(bomb[i].g,bomb[i].k)+1,bomb[i].t); cout<<t; if(i<n){ cout<<" "; e[bomb[i].l].emplace_back(E(t,bomb[i].d)); e[bomb[i].r+1].emplace_back(E(t,bomb[i].d)); }else cout<<"\n"; } for(i=1;i<=n+1;i++)e[i].clear(); } }
E. 地图编辑器
#include<iostream> using namespace std; const int N=15; int Case,n,m,k,i,j,x,y,f[N][N];char c[N][N]; inline void draw(int x,int y,int w){ if(x<1||y<1||y>m)return; c[x][y]=w; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>m>>k; for(i=1;i<=n;i++)for(j=1;j<=m;j++){ f[i][j]=0; c[i][j]='.'; } for(i=1;i<=k;i++){ cin>>x>>y; f[x][y]=i; } for(i=1;i<=n;i++)for(j=1;j<=m;j++){ x=f[i][j]; if(!x)continue; x+='0'; draw(i,j,x); draw(i-1,j,x); for(k=j-2;k<=j+2;k++)draw(i-2,k,x); for(k=j-1;k<=j+1;k++)draw(i-3,k,x); draw(i-4,j,x); } for(i=1;i<=n;i++){ for(j=1;j<=m;j++)cout<<c[i][j]; cout<<"\n"; } } }
F. 伤害冷却比
#include<iostream> using namespace std; typedef long long ll; int Case; ll mygcd(ll a,ll b){return b?mygcd(b,a%b):a;} struct Frac{ ll u,d; Frac(){} Frac(ll _u,ll _d){u=_u,d=_d;} void show(){ ll g=mygcd(u,d); cout<<u/g<<"/"<<d/g<<"\n"; } bool operator>=(const Frac&p)const{return u*p.d>=p.u*d;} }k,l,r; int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>k.u>>k.d>>l.u>>l.d>>r.u>>r.d; Frac tmp(k.u*r.d,k.d*r.u); ll v=tmp.u/tmp.d+1; Frac ans(r.u*v,r.d); if(tmp.u%tmp.d){ Frac x(k.u,k.d*v); if(x>=l){ Frac now(x.u*(v+1),x.d); if(now>=ans)ans=now; } } ans.show(); } }
G. 满员电车
#include<iostream> #include<algorithm> #include<vector> using namespace std; typedef pair<int,int>P; const int N=200005,M=1111111,inf=~0U>>1; int Case,n,m,ca,cb,q,i,x,S,T,d[N],cov[N],f[N]; int pos[N*2],mia[M],mxb[M],best[M]; P pool[N*2]; vector<int>ga[N],gb[N]; struct E{int t,l,r,p;}a[N],b[N]; void build(int x,int a,int b){ mia[x]=inf; mxb[x]=-1; best[x]=inf; if(a==b){ pos[a]=x; return; } int mid=(a+b)>>1; build(x<<1,a,mid); build(x<<1|1,mid+1,b); } inline void change(int x,int a,int b){ x=pos[x]; mia[x]=a; mxb[x]=b; for(x>>=1;x;x>>=1){ mia[x]=min(mia[x<<1],mia[x<<1|1]); mxb[x]=max(mxb[x<<1],mxb[x<<1|1]); best[x]=min(best[x<<1],best[x<<1|1]); if(mxb[x<<1]>=0&&mia[x<<1|1]<inf)best[x]=min(best[x],mia[x<<1|1]-mxb[x<<1]); } } inline int query(int S,int T){ if(cov[S])return d[T]-d[S]; if(f[S]==inf)return -1; return f[S]-d[n]+d[S]+d[T]; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>ca>>cb>>q; for(i=1;i<=n;i++)cin>>d[i]; for(i=1;i<=ca;i++){ cin>>a[i].t>>a[i].l>>a[i].r; pool[i]=P(a[i].t-d[n]+2*d[a[i].r],i); cov[a[i].l]++; cov[a[i].r+1]--; ga[a[i].r].emplace_back(i); } for(i=1;i<=cb;i++){ cin>>b[i].t>>b[i].l>>b[i].r; pool[i+ca]=P(b[i].t,-i); gb[b[i].l].emplace_back(i); gb[b[i].r+1].emplace_back(-i); } m=ca+cb; sort(pool+1,pool+m+1); for(i=1;i<=ca+cb;i++){ x=pool[i].second; if(x>0)a[x].p=i;else b[-x].p=i; } build(1,1,m); for(i=1;i<=n;i++){ for(const auto&it:ga[i])change(a[it].p,a[it].t,-1); for(const auto&it:gb[i])if(it>0)change(b[it].p,inf,b[it].t);else change(b[-it].p,inf,-1); cov[i]+=cov[i-1]; f[i]=best[1]; } while(q--){ cin>>S>>T; cout<<query(S,T)<<"\n"; } for(i=1;i<=n+1;i++){ cov[i]=0; ga[i].clear(); gb[i].clear(); } } }
H. 飞行训练
#include<iostream> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int N=50005,K=8,BLK=(N>>K)+1; int Case,n,m,i,j; vector<int>g[N]; ll ans; int rangel[N],ranger[N],pool[N*2],cb,st[BLK],en[BLK]; int at[BLK][N],cov[BLK][(1<<(K+1))+5],val[BLK][(1<<(K+1))+5],sz[BLK],sum[BLK]; struct E{int u,l,r,L,R;}e[N]; inline bool cmp(const E&a,const E&b){return a.u<b.u;} inline void init(){ int i,j,k,cp,_; for(i=1,j=0;i<=n;i++){ while(j<m&&e[j+1].u<=i)j++; ranger[i]=j; } for(i=n,j=m+1;i;i--){ while(j>1&&e[j-1].u>=i)j--; rangel[i]=j; } cb=m>>K; for(i=1;i<=m;i++)en[i>>K]=i; for(i=m;i;i--)st[i>>K]=i; pool[0]=0; for(i=0;i<=cb;i++){ sum[i]=0; pool[cp=1]=n; for(j=st[i];j<=en[i];j++){ pool[++cp]=e[j].l-1; pool[++cp]=e[j].r; } sort(pool,pool+cp+1); _=cp; cp=0; for(j=1;j<=_;j++)if(pool[j]>pool[j-1])pool[++cp]=pool[j]; sz[i]=cp; for(j=0;j<=cp;j++)cov[i][j]=val[i][j]=0; for(j=1;j<=cp;j++)for(k=pool[j-1]+1;k<=pool[j];k++)at[i][k]=j; for(j=st[i];j<=en[i];j++){ e[j].L=at[i][e[j].l]; e[j].R=at[i][e[j].r]; cov[i][e[j].L]++; cov[i][e[j].R+1]--; } for(j=1;j<=cp;j++)cov[i][j]+=cov[i][j-1]; } } inline void modify(int x,int p){ for(int i=0;i<=cb;i++){ int y=at[i][x]; sum[i]+=cov[i][y]*p; val[i][y]+=p; } } inline void ask(int o,int l,int r){ int i,m=sz[o]; for(i=1;i<=m;i++)pool[i]=pool[i-1]+val[o][i]; for(i=l;i<=r;i++)ans+=pool[e[i].R]-pool[e[i].L-1]; } inline void query(int l,int r){ l=rangel[l],r=ranger[r]; if(l>r)return; int L=l>>K,R=r>>K; for(int i=L+1;i<R;i++)ans+=sum[i]; if(L==R)ask(L,l,r); else{ ask(L,l,en[L]); ask(R,st[R],r); } } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>m; ans=0; for(i=1;i<=n+1;i++)g[i].clear(); for(i=1;i<=m;i++)cin>>e[i].u>>e[i].l>>e[i].r; sort(e+1,e+m+1,cmp); for(i=1;i<=m;i++){ g[e[i].l].emplace_back(i); g[e[i].r+1].emplace_back(-i); } init(); for(i=1;i<=n;i++){ for(const auto&it:g[i])if(it>0)modify(e[it].u,1);else modify(e[-it].u,-1); for(j=rangel[i];j<=ranger[i];j++)query(e[j].l,e[j].r); } cout<<ans<<"\n"; } }
I. 崭新的假日
#include<iostream> #include<algorithm> using namespace std; const int days[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; int Case,n,m,i,l,r,k,year,month,day,g[555],ans; inline bool check(int year,int month,int day){ if(month==2&&day==29&&year%4)return 0; if(month<3){ year-=1; month+=12; } int c=year/100,y=year-100*c; int w=c/4-2*c+y+y/4+(26*(month+1)/10)+day-1; w=(w%7+7)%7; return w>=1&&w<=5; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>k>>l>>r; n=0; for(month=1;month<=12;month++)for(day=1;day<=days[month];day++){ m=0; for(year=l;year<=r;year++)m+=check(year,month,day); g[++n]=m; } sort(g+1,g+n+1); ans=0; for(i=1;i<=k;i++)ans+=g[i]; cout<<ans<<"\n"; } }
J. 情报污染
#include<iostream> #include<algorithm> #include<cmath> #include<vector> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int>P; const int N=50005,M=50005,K=253,W=4,CNT=(M*2+K)*2+5,inf=~0U>>1; int Case,n,m,cnt,A,B,C,lim,i,x,y,u,v,w,o,pre[N]; P p[N]; vector<P>cons[N]; vector<int>g[CNT],h[CNT]; bool vis[CNT]; int scc,from[CNT],t,s[CNT]; ull mask[CNT][W],reach[CNT][W]; inline void add_edge(int x,int y){ g[x].emplace_back(y); h[y].emplace_back(x); } struct Pool{ vector<int>v; int st,len; bool big; void clear(){v.clear();} void ext(int x){v.emplace_back(x);} int find(int x){ int idx=lower_bound(v.begin(),v.end(),x)-v.begin(); return st+idx; } int get_prev(int x){ if(!len)return -1; const auto&it=lower_bound(v.begin(),v.end(),x); if(it==v.begin())return -1; int idx=it-v.begin(); return st+idx-1; } void build(){ sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); len=v.size(); st=cnt; cnt+=len; } void add_adj_edges(){ for(int i=1;i<len;i++){ add_edge(st+i-1,st+i); add_edge(st+i+cnt,st+i-1+cnt); } } void make_pre(){ big=len>lim; if(big)for(int i=0;i+1<len;i++)for(int j=v[i];j<v[i+1];j++)pre[j]=st+i; } }upper[N]; struct E{ int x,y,w; E(){} E(int _x,int _y,int _w){x=_x,y=_y,w=_w;} }e[M],a[M],b[M],c[K]; inline int dis(const P&a,const P&b){ ll dx=a.first-b.first,dy=a.second-b.second; ll tmp=dx*dx+dy*dy; ll ret=sqrt(tmp)-3; ret=max(ret,0LL); while(ret*ret<tmp)ret++; return ret; } inline void add_or(int x,int y){ add_edge(x+cnt,y); add_edge(y+cnt,x); } inline void add_nand(int x,int y){ add_edge(x,y+cnt); add_edge(y,x+cnt); } inline void add_constraints(const Pool&a,const Pool&b,int w){ if(b.big){ for(int i=0;i<a.len;i++){ int r=w-a.v[i]-1; if(r<b.v[0])return; add_nand(a.st+i,r<b.v[b.len-1]?pre[r]:(b.st+b.len-1)); } }else for(int i=0,j=b.len-1;i<a.len;i++){ while(j>=0&&a.v[i]+b.v[j]>=w)j--; if(j<0)return; add_nand(a.st+i,b.st+j); } } void dfs(int x){ vis[x]=1; for(const auto&y:h[x])if(!vis[y])dfs(y); s[++t]=x; } inline void go(int x){ static int q[CNT]; static ull now[W]; int h=1,t=1,i; q[1]=x; vis[x]=0; from[x]=++scc; for(i=0;i<W;i++)now[i]=0; while(h<=t){ x=q[h++]; for(i=0;i<W;i++)now[i]|=mask[x][i]; for(const auto&y:g[x])if(vis[y]){ q[++t]=y; vis[y]=0; from[y]=scc; }else if(from[y]<scc){ int z=from[y]; now[0]|=reach[z][0]; now[1]|=reach[z][1]; now[2]|=reach[z][2]; now[3]|=reach[z][3]; } } for(i=0;i<W;i++)reach[scc][i]=now[i]; } inline void up(int&x,int y){x>y?(x=y):0;} inline bool check(int x,int y){return reach[from[c[x].y]][y>>6]>>(y&63)&1;} inline int solve(){ int i,j; for(i=0;i<cnt;i++)if(from[i]==from[i+cnt])return 0; int ans=inf; for(i=0;i<C;i++){ if(check(i,i))up(ans,c[i].w); for(j=0;j<i;j++)if(check(i,j)&&check(j,i))up(ans,c[i].w+c[j].w); } if(ans==inf)ans=-1; return ans; } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n>>m>>A>>B>>C; for(i=0;i<n;i++)cin>>p[i].first>>p[i].second; for(i=0;i<m;i++){ cin>>x>>y; x--,y--; e[i]=E(x,y,dis(p[x],p[y])); } for(i=0;i<n;i++){ upper[i].clear(); cons[i].clear(); } for(i=0;i<A;i++){ cin>>x>>y>>w; x--,y--; a[i]=E(x,y,w); } for(i=0;i<B;i++){ cin>>x>>y>>w; x--,y--; b[i]=E(x,y,w); upper[x].ext(w); upper[y].ext(w); } for(i=0;i<C;i++){ cin>>x>>y>>w; x--; c[i]=E(x,y,w); upper[x].ext(y); } cnt=0; for(i=0;i<n;i++)upper[i].build(); for(i=0;i<cnt*2;i++){ g[i].clear(); h[i].clear(); for(o=0;o<W;o++)mask[i][o]=0; } for(i=0;i<A;i++){ x=a[i].x,y=a[i].y,w=a[i].w; u=upper[x].get_prev(w); v=upper[y].get_prev(w); if(~u&&~v)add_nand(u,v); } for(i=0;i<B;i++){ x=b[i].x,y=b[i].y,w=b[i].w; add_or(upper[x].find(w),upper[y].find(w)); } for(i=0;i<C;i++){ o=upper[c[i].x].find(c[i].y); c[i].x=o+cnt; c[i].y=o; mask[c[i].x][i>>6]|=1ULL<<(i&63); } for(i=0;i<n;i++)upper[i].add_adj_edges(); for(i=0;i<m;i++){ x=e[i].x,y=e[i].y; if(upper[x].len>upper[y].len)swap(x,y); cons[y].emplace_back(P(x,e[i].w)); } lim=sqrt((2.0*B*n)/max(m,1)); for(i=0;i<n;i++){ if(!upper[i].len||!cons[i].size())continue; upper[i].make_pre(); for(const auto&con:cons[i])add_constraints(upper[con.first],upper[i],con.second); } scc=t=0; for(i=0;i<cnt*2;i++)if(!vis[i])dfs(i); for(i=t;i;i--)if(vis[s[i]])go(s[i]); cout<<solve()<<"\n"; } }
K. 切披萨
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=200005; int Case,n,m,i,j,k,qa[N],qb[N],tmp[N],fin[N]; struct P{int x,y;}a[N]; struct Line{ int a,b;ll c; bool contain(const P&p)const{return 1LL*a*p.x+1LL*b*p.y<=c;} }b[N],hull[N]; ll lim[N]; inline ll pos(const Line&p,const Line&q){ return (p.c*q.b-q.c*p.b)/(1LL*p.a*q.b-1LL*q.a*p.b); } inline bool cmpa(int p,int q){return a[p].x<a[q].x;} inline bool cmpb(int p,int q){ ll cross=1LL*b[p].a*b[q].b-1LL*b[q].a*b[p].b; if(cross)return cross>0; return b[p].c*b[q].b>b[q].c*b[p].b; } inline bool cmpfin(int p,int q){return fin[p]==fin[q]?p<q:fin[p]<fin[q];} void solve(int al,int ar,int bl,int br){ int i,o; if(bl==br){ const Line&B=b[bl]; for(i=al;i<=ar;i++){ o=qa[i]; fin[o]=B.contain(a[o])?bl:m+1; } return; } int mid=(bl+br)>>1,t=0; for(i=bl;i<=br;i++){ o=qb[i]; if(o>mid)continue; const Line&now=b[o]; if(t&&1LL*hull[t].a*now.b==1LL*hull[t].b*now.a)continue; while(t>1&&pos(hull[t],now)<=lim[t-1])t--; if(t)lim[t]=pos(hull[t],now); hull[++t]=now; } int tl=al-1,tr=ar+1,h=1; for(i=al;i<=ar;i++){ o=qa[i]; while(h<t&&a[o].x>lim[h])h++; if(hull[h].contain(a[o]))tmp[++tl]=o;else tmp[--tr]=o; } reverse(tmp+tr,tmp+ar+1); for(i=al;i<=ar;i++)qa[i]=tmp[i]; int l=bl-1,r=mid; for(i=bl;i<=br;i++){ o=qb[i]; if(o<=mid)tmp[++l]=o;else tmp[++r]=o; } for(i=bl;i<=br;i++)qb[i]=tmp[i]; if(al<=tl)solve(al,tl,bl,mid); if(tr<=ar)solve(tr,ar,mid+1,br); } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n; for(i=1;i<=n;i++){ cin>>a[i].x>>a[i].y; qa[i]=i; } cin>>m; for(i=1;i<=m;i++){ cin>>b[i].a>>b[i].b>>b[i].c; qb[i]=i; } sort(qa+1,qa+n+1,cmpa); sort(qb+1,qb+m+1,cmpb); solve(1,n,1,m); sort(qa+1,qa+n+1,cmpfin); for(i=j=1;i<=m;i++){ for(k=j;k<=n&&fin[qa[k]]==i;k++); cout<<k-j; while(j<k)cout<<" "<<qa[j++]; cout<<"\n"; } } }
L. 字典树逆向
#include<iostream> #include<algorithm> #include<vector> using namespace std; typedef unsigned long long ull; const int N=200005,P=998244353,LESS=0,GREATER=1,SUB=2,CONTAIN=3,SAME=4; int Case,n,m,i,x,deg[N];vector<int>son[N]; int compare(int x,int y){ int n=deg[x],m=deg[y],i=0; if(!n&&!m)return SAME; if(!n)return LESS; if(!m)return GREATER; while(i<n&&i<m){ int t=compare(son[x][i],son[y][i]); if(t==SAME){ i++; continue; } if(t==SUB&&i+1<n)return GREATER; if(t==CONTAIN&&i+1<m)return LESS; return t; } if(i==n&&i==m)return SAME; return i==n?SUB:CONTAIN; } inline bool cmp(int x,int y){ if(x==y)return 0; int t=compare(x,y); return t==LESS||t==CONTAIN; } void dfs(int x,ull h){ if(!deg[x]){ cout<<h<<"\n"; } h*=P; for(int i=0;i<deg[x];i++)dfs(son[x][i],h+i+1); } int main(){ ios_base::sync_with_stdio(0);cin.tie(0); cin>>Case; while(Case--){ cin>>n; for(i=1;i<=n;i++)son[i].clear(); for(i=2;i<=n;i++){ cin>>x; son[x].emplace_back(i); } for(m=0,i=n;i;i--){ deg[i]=son[i].size(); if(deg[i]==0)m++;else sort(son[i].begin(),son[i].end(),cmp); } cout<<m<<"\n"; dfs(1,0); } }