Loading

noip模拟37

A. 数列

一个简单的\(exgcd\)
然而我忘了..

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define re register ll 
	#define lf double
	#define lbt(x) (x&(-x))
	#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) memcpy(x,y,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;

ll n,ans;
ll exgcd(ll a,ll b,ll &x,ll &y){
	if(!b){ x=1,y=0; return a; }
	ll d=exgcd(b,a%b,y,x);
	y=y-(a/b)*x; return d;
}
signed main(){
	ll a,b,x,y,w,t1,t2,d,temp;
	n=read(),a=read(),b=read();
	d=exgcd(a,b,x,y); a/=d,b/=d;
//	cout<<x<<' '<<y<<' '<<d<<endl;
	while(n--){
		w=abs(read()); temp=1e10;	
		if(w%d) { puts("-1"); return 0; }
		t1=x*w/d,t2=y*w/d; t2+=a*(t1/b),t1-=b*(t1/b);
		temp=min(temp,min(abs(t1)+abs(t2),abs(t1+b)+abs(t2-a)));
		temp=min(temp,min(abs(t1)+abs(t2),abs(t1-b)+abs(t2+a)));
		t1=x*w/d,t2=y*w/d; t1+=b*(t2/a),t2-=a*(t2/a);
		temp=min(temp,min(abs(t1)+abs(t2),abs(t1+b)+abs(t2-a)));
		temp=min(temp,min(abs(t1)+abs(t2),abs(t1-b)+abs(t2+a)));
		ans+=temp;
	}
	printf("%lld\n",ans);
	return 0;
}

B. 数对

类似于曾经做过的一道队长快跑,但是比那道题难度要增加,然而我就是打的队长快跑..
于是挂了..

一道显然的线段树维护Dp.
这道题,我们可以发现和\(a\)\(b\)都有关.
于是可以按照\(a+b\)排序.
当然按照\(a*b\)排序也可以.
只要和\(a\)\(b\)都有关即可..
\(f_{i,j}\)表示前\(i\)个数中,已选的数的\(Max_a\)\(j\)的最大价值,
然后根据状态转移并线段树维护即可.

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int 
	#define ull unsigend ll
	#define re register ll 
	#define lf double
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#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(x,y,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 n,cnt;
ll lsh[N<<2];
struct I { ll a,b,w,sum; } p[N];
struct II { ll w,lazy; } tr[N<<3];
void spread(ll x){
	if(tr[x].lazy){
		tr[x<<1].w+=tr[x].lazy;
		tr[x<<1|1].w+=tr[x].lazy;
		tr[x<<1].lazy+=tr[x].lazy;
		tr[x<<1|1].lazy+=tr[x].lazy;
		tr[x].lazy=0;
	}
	return ;
}
void pushup(ll x){
	tr[x].w=max(tr[x<<1].w,tr[x<<1|1].w);
	return ;
}
ll query(ll x,ll l,ll r,ll ql,ll qr){
	if(ql>qr) return 0;
	if(l>=ql and r<=qr){
		return tr[x].w;
	}
	spread(x); ll mid=(l+r)>>1; 
	ll temp=0;
	if(ql<=mid) temp=max(temp,query(x<<1,l,mid,ql,qr));
	if(qr>=mid+1) temp=max(temp,query(x<<1|1,mid+1,r,ql,qr));
	pushup(x);
	return temp;
}
void change(ll x,ll l,ll r,ll pos,ll w){
	if(l==r){
		tr[x].w=max(tr[x].w,w);
		return ;
	}
	spread(x); ll mid=(l+r)>>1;
	if(pos<=mid) change(x<<1,l,mid,pos,w);
	else change(x<<1|1,mid+1,r,pos,w);
	pushup(x); return ;
}
void update(ll x,ll l,ll r,ll ql,ll qr,ll w){
	if(ql>qr) return ;
	if(l>=ql and r<=qr){
		tr[x].w+=w; tr[x].lazy+=w;
		return ;
	}
	spread(x); ll mid=(l+r)>>1;
	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); return ;
}
inline bool comp(I i,I j){ return i.sum<j.sum; }
signed main(){
	srand(time(0));
	ll t0=clock();
	n=read(); ll w;
	for(re i=1;i<=n;i++){
		lsh[++cnt]=p[i].a=read(); 
		lsh[++cnt]=p[i].b=read();
		p[i].sum=p[i].a+p[i].b;
		p[i].w=read();
	}
	sort(p+1,p+1+n,comp); sort(lsh+1,lsh+1+cnt);
	cnt=unique(lsh+1,lsh+1+cnt)-lsh-1;
	ll res,ans=0;
	for(re i=1;i<=n;i++) 
	{
		p[i].a=lb(lsh+1,lsh+1+cnt,p[i].a)-lsh,p[i].b=lb(lsh+1,lsh+1+cnt,p[i].b)-lsh;
//		cout<<p[i].a<<' '<<p[i].b<<' '<<p[i].w<<endl;
	}
	for(re i=1;i<=n;i++){
		update(1,1,cnt,p[i].a+1,p[i].b,p[i].w);
		res=query(1,1,cnt,1,min(p[i].a,p[i].b));
		change(1,1,cnt,p[i].a,res+p[i].w);
	}
	printf("%lld",tr[1].w);
	return 0;
}

C. 最小距离

暴力很好打,但是遍历到的无用情况太多..
维护每个点所和最近的特殊点的最短距离,
并记录是和哪个点的最短距离,
然后枚举每条边,如果两个端点所最靠近的特殊点不一样,那么更新这两个特殊点的答案..
正确性显然.

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int 
	#define ull unsigend ll
	#define re register ll 
	#define lf double
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#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(x,y,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=2e5+51;

ll m,n,s,ts;
ll id[N],head[N],vis[N],dis[N],ans[N],sp[N];
struct I { ll u,v,w,nxt; } e[N<<1];
inline void add(ll u,ll v,ll w){	
	e[++ts].u=u; e[ts].v=v;
	e[ts].w=w; e[ts].nxt=head[u];
	head[u]=ts;
}
queue<ll> que;
inline void Spfa(){
	for(re i=1;i<=s;i++) que.push(id[i]);
	for(re i=1;i<=n;i++) dis[i]=1e11*(!sp[i]);
	ll now;
	while(que.size()){
		now=que.front(); que.pop();
		for(re i=head[now];i;i=e[i].nxt){
			if(dis[e[i].v]>dis[now]+e[i].w){	
				dis[e[i].v]=dis[now]+e[i].w;
				sp[e[i].v]=sp[now];
				if(!vis[e[i].v]) que.push(e[i].v);
				vis[e[i].v]=1;
			}
		}
		vis[now]=0;
	}
//	for(re i=1;i<=n;i++) cout<<dis[i]<<" "<<sp[i]<<'\n';
	return ;
}
signed main(){
	n=read(); m=read(); s=read();
	for(re i=1;i<=s;i++) id[i]=read(),sp[id[i]]=id[i];
	ll u,v,w;
	for(re i=1;i<=m;i++){
		u=read(),v=read(),w=read();
		add(u,v,w); add(v,u,w);
	}
	Spfa();
	Fill(ans,0x3f);
	for(re i=1;i<=ts;i++){
	//	cout<<e[i].u<<" "<<e[i].v<<" "<<sp[e[i].u]<<' '<<sp[e[i].v]<<'\n';
		if(sp[e[i].u]!=sp[e[i].v]){
			ans[sp[e[i].u]]=min(e[i].w+dis[e[i].u]+dis[e[i].v],ans[sp[e[i].u]]);
			ans[sp[e[i].v]]=min(e[i].w+dis[e[i].u]+dis[e[i].v],ans[sp[e[i].v]]);
		}
	}
	for(re i=1;i<=s;i++) printf("%lld ",ans[id[i]]);
	return 0;
}

D. 真相

考场上以为动态开点能过,于是忘记了优化,
然后\(TLE\)掉了\(35pts\)..
其实这道题的优化应该是挺能想到的..
发现每两个美元符号所对应的点之前的区间(左闭右开)都只和右端点的美元符号是否真实有关,
也就是做每个区间的时候可以看成相互独立.

代码中记录的一些信息可以被替换或删减,码风有点潦草,请自行筛选与改善.

D_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define re register 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) memcpy(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=1e6+51;
ll m,n,Ts,flag,alls;
ll g[N],tf[N],t[N];
ll pre[3][N],ans[3][N];
map<ll,ll> map1;
vector<ll> vec,v;
inline void Pre(){
	for(re i=0;i<=n+1;i++) tf[i]=0,g[i]=0,t[i]=0,pre[1][i]=0,pre[2][i]=0,ans[1][i]=0,ans[2][i]=0;
	map1.clear(); vec.clear(); v.clear();
	flag=0; alls=0;
}
inline void Init(){
	n=read(); char s[5];
	for(ll i=1;i<=n;i++){
		scanf("%s",s+1);
		if(s[1]=='+') g[i]=-2;
		else if(s[1]=='-') g[i]=-1;
		else g[i]=read(),flag=max(flag,i);
	}
	return ;
}
inline ll inc(ll i,ll j){ return i+j>n ? i+j-n : i+j; }
inline void Work_None(){
	for(re i=0;i<=n+1;i++) tf[i]=0;
	for(auto i : v) tf[i]=-1;
	for(re i=n;i>=2;i--){
		if(g[i-1]>=0) continue;
		if((g[i-1]==-1) xor (tf[i]==-1)) tf[i-1]=-1;
		else tf[i-1]=1;
	}
	ll res=0;
	for(re i=1;i<=n;i++) res+=(tf[i]==1);
	for(auto i : vec){
		if(i==res){
			puts("inconsistent");
			return ;
		} 
	}
	puts("consistent");	
	return ;
}
inline void Work(){
 	if(flag){
 	 	ll res=n-flag;
		for(re i=1;i<=n;i++) t[inc(i,res)]=g[i];
		for(re i=1;i<=n;i++) g[i]=t[i];
	 	for(ll i=1;i<=n;++i){
			if(g[i]>=0){
				v.push_back(i);
				if(g[i]>n) continue;
				if(map1.find(g[i])==map1.end()) vec.push_back(g[i]);
				map1[g[i]]=1;
			}
		}
		for(auto i : v){
			tf[i]=1; pre[1][i]=1;
			for(re j=i;j>=2;j--){
				if(g[j-1]>=0) break;
				if((g[j-1]==-1) xor (tf[j]==-1)) tf[j-1]=-1;
				else pre[1][i]++,tf[j-1]=1;
			}
			tf[i]=-1;
			for(re j=i;j>=2;j--){
				if(g[j-1]>=0) break;
				if((g[j-1]==-1) xor (tf[j]==-1)) tf[j-1]=-1;
				else pre[2][i]++,tf[j-1]=1;
			}
		}
		for(auto j : v){
			if(j>n) continue;
			ans[1][g[j]]+=pre[1][j];
			ans[2][g[j]]+=pre[2][j];
		}
		for(auto i : vec) alls+=ans[2][i];
		for(auto i : vec){
			if(i==ans[1][i]+alls-ans[2][i]){
				puts("consistent");
				return ;
			}
		}
		Work_None();
	}
	else{
		tf[1]=1;
		for(re i=1;i<=n-1;i++){
			if((tf[i]==-1) xor (g[i]==-1)) tf[i+1]=-1;
			else tf[i+1]=1;
		}
		if(((tf[n]==-1) xor (g[n]==-1))!=tf[1]){
			puts("consistent");
			return ;
		}
		tf[1]=-1;
		for(re i=1;i<=n-1;i++){
			if((tf[i]==-1) xor (g[i]==-1)) tf[i+1]=-1;
			else tf[i+1]=1;
		}
		if(((tf[n]==-1) xor (g[n]==-1)) and (tf[1]==-1)){
			puts("consistent");
			return ;
		}
		puts("inconsistent");
		return ;
	}
	return ;
}
signed main(){
	Ts=read();
	while(Ts--){
		Pre();
		Init(); Work();
	}
	return 0;
}
posted @ 2021-08-14 21:08  AaMuXiiiiii  阅读(31)  评论(0编辑  收藏  举报