noip模擬40(待補)
阿新 • • 發佈:2021-08-19
A. 送花
不知道該怎麼評價自己想到了線段樹優化\(dp\)但覺得第一題不會考\(dp\)所以不再往下考慮的想法.
如果我們找到了和之前相同的值,直接減掉這個權值的貢獻就可以了..
大概就是將所有狀態都枚舉了出來然後用線段樹優化直接取最大值.
A_code
#include<bits/stdc++.h> using namespace std; namespace BSS { #define ll long long int #define re register int #define ull unsigned ll #define lf double #define lb lower_bound #define ub upper_bound #define mp make_pair #define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout) #define Fill(x,y) memset(x,y,sizeof x); #define Copy(x,y) memset(y,x,sizeof x); inline ll read() { ll ss=0; bool cit=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') cit=0; while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar(); return cit?ss:-ss; } } using namespace BSS; const ll N=2e6+51; ll m,n,ans; ll c[N],d[N]; pair<ll,ll> p[N]; struct I { ll sum,lazy; } tr[N<<2]; inline void spread(ll x){ if(tr[x].lazy){ tr[x<<1].sum+=tr[x].lazy,tr[x<<1|1].sum+=tr[x].lazy, tr[x<<1].lazy+=tr[x].lazy,tr[x<<1|1].lazy+=tr[x].lazy; tr[x].lazy=0; } } inline void pushup(ll x){ tr[x].sum=max(tr[x<<1].sum,tr[x<<1|1].sum); } void update(ll x,ll l,ll r,ll ql,ll qr,ll w){ if(ql>qr or (!qr) ) return ; if(l>=ql and r<=qr){ tr[x].sum+=w,tr[x].lazy+=w; return ; } ll mid=(l+r)>>1; spread(x); if(ql<=mid) update(x<<1,l,mid,ql,qr,w); if(qr>=mid+1) update(x<<1|1,mid+1,r,ql,qr,w); pushup(x); } signed main(){ n=read(); m=read(); for(re i=1;i<=n;++i) c[i]=read(); for(re i=1;i<=m;++i) d[i]=read(),p[i].first=0,p[i].second=0; ll l,r; for(re i=1;i<=n;++i){ l=p[c[i]].first,r=p[c[i]].second; p[c[i]].first=r,p[c[i]].second=i; update(1,1,n,l+1,r,-d[c[i]]),update(1,1,n,r+1,i,d[c[i]]); ans=max(ans,tr[1].sum); // cout<<"ans:"<<ans<<'\n'; } printf("%lld\n",ans); return 0; }
B. 星空
發現最小距離一定是不為\(0\)的直接距離..
一個我又不會的巧妙轉化:
題目中讓我們求:
\(|\ |x_1-x_2|\ -\ |y_1-y_2|\ |\)
然後我們四十五度翻轉座標系.
於是\((x,y)\)座標變為了\((x+y,x-y)\)..
設新的座標為\((r,c)\).
直接距離就是\(min(\ |r_1-r_2|\ ,\ |c_1-c_2|\ )\).然後我們可以考慮將所有距離為\(0\)的點進行並查集縮點.
然後列舉所有的邊,如果這條邊的長度即為第一問的答案,那麼乘積累加並注意去重即可.
B_code
#include<bits/stdc++.h> using namespace std; namespace BSS { #define ll long long int #define re register int #define ull unsigned ll #define lf double #define lb lower_bound #define ub upper_bound #define mp make_pair #define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout) #define Fill(x,y) memset(x,y,sizeof x); #define Copy(x,y) memset(y,x,sizeof x); inline ll read() { ll ss=0; bool cit=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') cit=0; while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar(); return cit?ss:-ss; } } using namespace BSS; const ll N=1e5+51; ll m,n,dis,ans; ll fa[N]; struct I { ll x,y,id; } p[N]; inline bool comp1(I i,I j){ return i.x<j.x; } inline bool comp2(I i,I j){ return i.y<j.y; } ll find(ll x){ return x==fa[x] ? x : (fa[x]=find(fa[x])) ; } unordered_map<ll,ll> siz; map<pair<ll,ll>,ll> map1; vector<pair<ll,ll> > vec; signed main(){ n=read(); ll x,y; dis=1e10,p[0].x=1e10,p[0].y=1e10; for(re i=1;i<=n;++i) x=read(),y=read(),p[i].x=x+y,p[i].y=y-x,p[i].id=i; sort(p+1,p+1+n,comp1); for(re i=1;i<=n;++i){ if(p[i].x!=p[i-1].x) fa[p[i].id]=p[i].id; else fa[p[i].id]=find(p[i-1].id); } sort(p+1,p+1+n,comp2); for(re i=1;i<=n;++i) if(p[i].y==p[i-1].y) fa[find(p[i].id)]=find(fa[p[i-1].id]); for(re i=1;i<=n-1;++i) if(find(p[i].id)!=find(p[i+1].id)){ x=abs(p[i].y-p[i+1].y); if(dis>x){ vec.clear(); dis=x; x=min(p[i].id,p[i+1].id),y=max(p[i].id,p[i+1].id); vec.push_back(mp(x,y)); } else if(dis==x){ x=min(p[i].id,p[i+1].id),y=max(p[i].id,p[i+1].id); vec.push_back(mp(x,y)); } } sort(p+1,p+1+n,comp1); for(re i=1;i<=n-1;++i) if(find(p[i].id)!=find(p[i+1].id)){ x=abs(p[i].x-p[i+1].x); if(dis>x){ vec.clear(); dis=x; x=min(p[i].id,p[i+1].id),y=max(p[i].id,p[i+1].id); vec.push_back(mp(x,y)); } else if(dis==x){ x=min(p[i].id,p[i+1].id),y=max(p[i].id,p[i+1].id); vec.push_back(mp(x,y)); } } if(vec.empty()) { puts("-1"); return 0; } sort(vec.begin(),vec.end()); ll newsize=unique(vec.begin(),vec.end())-vec.begin(); vec.resize(newsize); for(re i=1;i<=n;++i) ++siz[find(i)]; for(auto i : vec){ x=find(i.first),y=find(i.second); if((!map1[mp(x,y)]) and (!map1[mp(y,x)])) ans+=siz[x]*siz[y]; map1[mp(x,y)]=1,map1[mp(y,x)]=1; } printf("%lld\n%lld",dis,ans); return 0; }