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);
}
}

浙公網安備 33010602011771號