Loading

noip模拟80

A. 邻面合并

考场上别人一看都像是插头 \(dp\),之前没学,尽管这题不是插头,但是状压还是很容易看出的.

自己设的 \(dp\) 状态太烂了,只空间就需要三维,而且转移写起来还很麻烦.

别人可以想到用 \(0/1\) 表示开头,但是自己考场上却是咋也想不到.

最近很多自己想的 \(dp\) 都很烂,大部分都是因为很多没用的状态自己非要去枚举或者特判.

甚至自己一点儿 \(dp\) 技巧都没有.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll int
	#define ull unsigned ll
	#define lf double
	#define lbt(x) ((x)&(-(x)))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	inline ll read() {
		ll w=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
		return cit?w:-w;
	}
} using namespace BSS;

const ll N=105,M=9,W=(1<<8)+25;

ll m,n,U,ans;
ll zt[N],num[W];
ll dp[N][W],cs[N][N];
auto check=[](ll x,ll s)->bool{
	ll lst=0;
	for(ll i=1;i<=m;i++){
		if((!cs[x][i]) and ((s>>i-1)&1)) return 0;
		if((s>>i-1)&1) lst=1;
		if(!cs[x][i]) lst=0;
		if(cs[x][i] and (!lst)) return 0;
	}
	return 1;
};
auto calc=[](ll x,ll s,ll t,ll pos)->bool{
	for(ll i=pos;i<=m;i++){
		if(((t>>i-1)&1)and(!cs[x-1][i])) return 0;
		if(((s>>i-1)&1)and(!cs[x][i])) return 0;
		if(cs[x][i]!=cs[x-1][i]) return 1;
		if(((s>>i-1)&1)xor((t>>i-1)&1)) return 1;
		if((!cs[x][i]) and (!cs[x-1][i])) return 0;
	}
	return 0;
};
auto unit=[](ll x,ll s,ll t)->ll{
	ll res=0;
	for(ll i=1;i<=m;i++){
		if(((s>>i-1)&1) and ((t>>i-1)&1)) res+=calc(x,s,t,i);
		else res+=((t>>i-1)&1);
	}
	// cout<<x<<' '<<s<<' '<<t<<' '<<res<<endl;
	return res;
};
signed main(){
	File(merging);
	n=read(),m=read(),U=(1<<m)-1,ans=2e8;
	for(ll i=1;i<=n;i++){
		for(ll j=1;j<=m;j++) cs[i][j]=read();
	}
	Fill(dp,0x3f),dp[0][0]=0; ll res,cnt,flag,nowcnt;
	for(ll i=1;i<=U;i++) num[i]=num[i&(i-1)]+1;
	for(ll i=1;i<=n;i++){
		for(ll j=0;j<=U;j++){
			if(!check(i,j)) continue;
			for(ll k=0;k<=U;k++){
				if(!check(i-1,k)) continue;
				dp[i][j]=min(dp[i][j],dp[i-1][k]+unit(i,k,j));
			}
		}
	}
	for(ll i=0;i<=U;i++) ans=min(ans,dp[n][i]);
	printf("%d\n",ans),exit(0);
}

B. 光线追踪

一看就是线段树,自己还是想得麻烦了.

可以选择开两棵线段树,但是自己却非要维护斜率,维护的还是错的.

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long 
	#define ull unsigned ll
	#define lf long double
	#define lbt(x) ((x)&(-(x)))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	inline ll read() {
		ll w=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
		return cit?w:-w;
	}
} using namespace BSS;

#define ls (x<<1)
#define rs (x<<1|1)

const ll N=2e5+21,inf=1e10;
const lf eps=1e-8;


ll m,n,ops,cnt,ansxx,ansyy;
lf lsh[N<<2];
struct I { ll opt; lf x0,y0,x2,y2; } q[N];
struct II { ll w[2]; } tr[N<<2];
auto zz=[](lf x)->bool{ return x-eps<=0 and x+eps>=0; };
auto slope=[](ll x,ll y)->lf{ return zz(x) ? inf : 1.0*y/((lf)x); };
auto comp=[](ll i,ll j,ll op)->ll{ 
	if(!(i and j)) return i+j;
	if(op){
		if(q[i].y0==q[j].y0) return max(i,j);
		return ( (q[i].y0<q[j].y0) ? i : j ) ;
	}
	if(q[i].x0==q[j].x0) return max(i,j);
	return ( (q[i].x0<q[j].x0) ? i : j );
};
void update(ll x,ll l,ll r,ll ql,ll qr,ll id,ll op){
	if(ql>qr) return ; 
	if(l>=ql and r<=qr){
		tr[x].w[op]=comp(tr[x].w[op],id,op);
		// if(tr[x].w[op]==2 and id==2) cout<<l<<' '<<r<<' '<<ql<<' '<<qr<<' '<<lsh[l]<<' '<<lsh[r]<<' '<<id<<' '<<op<<" der\n";
		return ;
	}
	ll mid=(l+r)>>1;
	if(ql<=mid) update(ls,l,mid,ql,qr,id,op);
	if(qr>mid) update(rs,mid+1,r,ql,qr,id,op);
}
ll query(ll x,ll l,ll r,ll qpos,ll op){
	// cout<<"x:"<<x<<' '<<qpos<<' '<<l<<' '<<r<<' '<<lsh[l]<<' '<<lsh[r]<<' '<<op<<' '<<tr[x].w[op]<<endl;
	if(l==r) return tr[x].w[op]; ll mid=(l+r)>>1,res;
	res= ( qpos<=mid ? query(ls,l,mid,qpos,op) : query(rs,mid+1,r,qpos,op) );
	return comp(res,tr[x].w[op],op);
}
signed main(){
	File(raytracing);
	ops=read(); lf x0,y0,x2,y2,sp1,sp2,sp3,p1,p2,p3; ll ansx,ansy,opt;
	for(ll i=1;i<=ops;i++){
		q[i].opt=read();
		if(q[i].opt&1){
			x0=read(),y0=read(),x2=read(),y2=read();
			q[i].x0=x0,q[i].y0=y0,q[i].x2=x2,q[i].y2=y2;
			lsh[++cnt]=slope(x0,y0),lsh[++cnt]=slope(x0,y2),lsh[++cnt]=slope(x2,y0);
		}
		else{
			q[i].x0=read(),q[i].y0=read();
			lsh[++cnt]=slope(q[i].x0,q[i].y0);
		}
	}
	sort(lsh+1,lsh+1+cnt),cnt=unique(lsh+1,lsh+1+cnt)-lsh-1,n=cnt;
	// cout<<"lsh: "; for(ll i=1;i<=n;i++) cout<<lsh[i]<<' '; puts("");
	for(ll i=1;i<=ops;i++){
		if(q[i].opt&1){
			x0=q[i].x0,y0=q[i].y0,x2=q[i].x2,y2=q[i].y2;
			if(!x0) ansyy=comp(ansyy,i,1);
			if(!y0) ansxx=comp(ansxx,i,0);
			sp1=slope(x2,y0),sp2=slope(x0,y0),sp3=slope(x0,y2);
			p1=lb(lsh+1,lsh+1+cnt,sp1)-lsh;
			p2=lb(lsh+1,lsh+1+cnt,sp2)-lsh;
			p3=lb(lsh+1,lsh+1+cnt,sp3)-lsh;
			// cout<<sp1<<' '<<sp2<<' '<<sp3<<' '<<p1<<' '<<p2<<' '<<p3<<" skr\n";
			update(1,1,n,p1,p2,i,1); // 1 表示 y
			update(1,1,n,p2,p3,i,0); // 0 表示 x
		}
		else{
			sp1=slope(q[i].x0,q[i].y0),p1=lb(lsh+1,lsh+1+cnt,sp1)-lsh;
			if(sp1==0) { printf("%lld\n",ansxx); continue; }
			if(sp1==inf) { printf("%lld\n",ansyy); continue; }
			ansx=query(1,1,n,p1,0),ansy=query(1,1,n,p1,1);
			y0=1.0*q[ansx].x0*q[i].y0/(1.0*q[i].x0);
			if(!(ansx and ansy)) printf("%lld\n",ansx+ansy);
			else{
				if(y0==q[ansy].y0) printf("%lld\n",max(ansx,ansy));
				else printf("%lld\n",((y0<q[ansy].y0)?ansx:ansy));
			}
		}
	}
	exit(0);
}
/*
3
1 2 3 4 7 
1 3 5 8 10 
2 4 3 

*/

C. 百鸽笼

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long 
	#define ull unsigned ll
	#define lf long double
	#define lbt(x) ((x)&(-(x)))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	inline ll read() {
		ll w=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
		return cit?w:-w;
	}
} using namespace BSS;

const ll N=32,mod=998244353;

ll m,n,sum;
ll pre[N],val[N],ans[N],frc[N*N],inv[N*N];
ll g[N][N*N],f[N][N*N],C[N*N][N*N];
auto ksm=[](ll a,ll b,ll c)->ll{
	a%=c; ll w=1;
	for(;b;b>>=1,a=a*a%c) if(b&1) w=w*a%c;
	return w%c;
};
signed main(){
	File(c);
	n=read(); 
	for(ll i=1;i<=n;i++) pre[i]=pre[i-1]+(val[i]=read());
	frc[0]=1,frc[1]=1,inv[1]=1;
	for(ll i=2;i<=pre[n];i++) frc[i]=frc[i-1]*i%mod,inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for(ll i=0;i<=pre[n];i++){
		C[i][0]=1;
		for(ll j=1;j<=i;j++){
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
		}
	}
	g[0][0]=1;
	for(ll i=1;i<=n;i++){
		pre[i]=pre[i-1]+val[i]-1;
		for(ll j=i;j>0;j--)
			for(ll k=pre[n];k>=0;k--)
				for(ll h=0;h<val[i] and h<=k;h++)
					g[j][k]=(g[j][k]-g[j-1][k-h]*C[k][h]%mod+mod)%mod;
	}
	for(ll i=1;i<=n;i++){
		Copy(f,g);
		for(ll j=1;j<n;j++){
			for(ll k=0;k<=pre[n]-val[i]+1;k++){
				for(ll h=0;h<val[i] and h<=k;h++)
					f[j][k]=(f[j][k]+f[j-1][k-h]*C[k][h]%mod)%mod;
			}
		}
		for(ll j=0;j<n;j++){
			for(ll k=0;k<=pre[n]-val[i]+1;k++){
				// cout<<f[j][k]<<' ';
				ans[i]=(ans[i]+f[j][k]*C[k+val[i]-1][k]%mod*ksm(inv[j+1],k+val[i],mod)%mod)%mod;
			}
			// puts("");
		}
	}
	for(ll i=1;i<=n;i++) printf("%lld ",ans[i]);
	exit(0);
}

D. 滑稽树下你和我

\(Yubai\) 画了漂漂亮亮美美丽丽的图,建议去欣赏.

D_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long 
	#define ull unsigned ll
	#define lf long double
	#define lbt(x) ((x)&(-(x)))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	inline ll read() {
		ll w=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
		return cit?w:-w;
	}
} using namespace BSS;

const ll N=2e3+21,inf=1e10;
const lf eps=1e-8;

lf ans;
ll m,n,ts,cnt,sx,sy;
ll d[N],xi[N],yi[N],head[N];
ll vis[N][N];
lf dis[N][N],f[N][N];
struct I { 
	ll u,v; lf w;
	I(){}
	I(ll u_,ll v_,lf w_) : u(u_),v(v_),w(w_) {}
	friend bool operator < (I i,I j){
		return i.w>j.w;
	}
};
struct II { ll u,v,nxt; } e[N<<1];
struct III { ll u,v; } o[N];
priority_queue<I> que;
auto add=[](ll u,ll v)->void{
	e[++ts].u=u,e[ts].v=v,e[ts].nxt=head[u];
	head[u]=ts,d[u]++;
};
auto zz=[](lf w)->lf{ return (w-eps<=0 and w+eps>=0) ? 0 : w ; };
auto calc=[](ll i,ll j)->lf{ 
	return sqrt(1.0*(xi[i]-xi[j])*(xi[i]-xi[j])+1.0*(yi[i]-yi[j])*(yi[i]-yi[j]));
};
auto love=[](pair<lf,lf> i,pair<lf,lf> j)->lf{
	return i.first*j.first+i.second*j.second;
};
auto solve=[](ll i,ll j)->lf{
	ll u=o[j].u,v=o[j].v;
	pair<lf,lf> ab=mp(xi[v]-xi[u],yi[v]-yi[u]),ac=mp(xi[i]-xi[u],yi[i]-yi[u]);
	lf w=love(ab,ac)/calc(u,v);
	if(w<0 or w>calc(u,v)) return min(calc(i,u),calc(i,v));
	return sqrt(calc(i,u)*calc(i,u)-w*w);
};
signed main(){
	File(tree);
	n=read(),cnt=n,sx=read(),sy=read(); ll u,v;
	for(ll i=1;i<=n;i++) xi[i]=read(),yi[i]=read();
	for(ll i=2;i<=n;i++){
		u=read(),v=read(),o[++cnt].u=u,o[cnt].v=v;
		add(u,cnt),add(cnt,u),add(v,cnt),add(cnt,v);
	}
	ans=1e15;
	for(ll i=1;i<=n;i++){
		for(ll j=i;j<=n;j++) dis[i][j]=calc(i,j),dis[j][i]=dis[i][j];
		for(ll j=n+1;j<=cnt;j++) dis[i][j]=solve(i,j),dis[j][i]=dis[i][j];
	}
	for(ll i=1;i<=cnt;i++){
		for(ll j=1;j<=cnt;j++) f[i][j]=inf;
	}
	// for(ll i=1;i<=n;i++){
	// 	for(ll j=1;j<=cnt;j++) cout<<dis[i][j]<<' ';
	// 	puts("");
	// }
	// puts("");
	// que.push(mp(sx,sy)); pair<ll,ll> x;
	f[sx][sy]=dis[sx][sy];
	I x; que.push(I(sx,sy,f[sx][sy]));
	while(que.size()){
		x=que.top(),que.pop(),u=x.u,v=x.v;
		if(vis[u][v]) continue; vis[u][v]=1;
		for(ll i=head[u];i;i=e[i].nxt){
			if(f[e[i].v][v]>max(f[u][v],dis[e[i].v][v])){
				f[e[i].v][v]=max(f[u][v],dis[e[i].v][v]);
				que.push(I(e[i].v,v,f[e[i].v][v]));
			}
		}
		for(ll i=head[v];i;i=e[i].nxt){
			if(f[u][e[i].v]>max(f[u][v],dis[u][e[i].v])){
				f[u][e[i].v]=max(f[u][v],dis[u][e[i].v]);
				que.push(I(u,e[i].v,f[u][e[i].v]));
			}
		}
	}
	// for(ll i=1;i<=n;i++){
		// printf("%.5Lf\n",f[i][i]);
	// }
	// for(ll i=1;i<=n;i++){
	// 	for(ll j=1;j<=n;j++) printf("%Lf ",f[i][j]);
	// 	puts("");
	// }
	for(ll i=1;i<=n;i++){
		if(d[i]>1) continue;
		for(ll j=1;j<=n;j++){
			if(d[j]>1) continue; ans=min(ans,min(f[i][j],f[j][i]));
		}
	}
	printf("%.6Lf\n",ans),exit(0);
}
posted @ 2021-10-19 15:26  AaMuXiiiiii  阅读(42)  评论(0编辑  收藏  举报