1. 程式人生 > 其它 >noip模擬40(待補)

noip模擬40(待補)

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

C. 零一串