补题记录 | 10.4 waiting for 沈阳

 QOJ-2901 Hopscotch 500

题意:

给定n*n的棋盘,每一个格有对应的值,玩家从1跳到k,每一步的代价是min[(x_{1}-x_{2})^{2},(y_{1}-y_{2})^{2}],问总的代价的最小值。

题解思路:

从p状态转移到p+1状态,假设p状态我们已知到每一行和每一列的最小代价,我们去算p+1合法状态每一个点从每一行每一列转移来的代价并且更新。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define inf 0x3f3f3f3f3f3f3f
typedef long long ll;
int a[510][510];
//int dpx[510],dpy[510],nx[510],ny[510];
vector<pair<int,int>>v[251000];

int f(int x,int y) {
	return (x-y)*(x-y);
}
int n,k;
void solve() {
	cin>>n>>k;
	for(int i=1; i<=n; i++) {
		for(int j=1,x; j<=n; j++) {
			cin>>x;
			v[x].push_back({i,j});
		}
	}
	vector<int>dpx(n+1,inf),dpy(n+1,inf);

	for(auto vi:v[1]) {
		int x=vi.fi;
		int y=vi.se;
		dpx[x]=dpy[y]=0;
	}
	for(int i=2; i<=k; i++) {
		vector<int>nx(n+1,inf),ny(n+1,inf);
		for(auto vi:v[i]) {
			int x=vi.fi;
			int y=vi.se;

			int mn=inf;
			for(int j=1; j<=n; j++) {
				mn=min(mn,dpx[j]+f(j,x));
				mn=min(mn,dpy[j]+f(j,y));
			}

			nx[x]=min(mn,nx[x]);
			ny[y]=min(mn,ny[y]);
		}

		dpx=nx;
		dpy=ny;
	}

	int ans=inf;

	for(int i=1; i<=n; i++) {
		ans=min({dpx[i],dpy[i],ans});
	}

	if(ans==inf)cout<<-1<<'\n';
	else cout<<ans<<'\n';
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
//	cin>>t;
	while(t--)solve();
	return 0;
}

A National Pandemic

题意:树图,有三种操作:操作1 在x点爆发w严重值,其他所有点受w-dis(i,x)的严重影响。操作2 x点严重值 与0 取min。 操作3询问 x点严重值。

解题思路:

树链剖分+树上差分的操作。

做题时处理操作2出现问题,把pre+=w改成pre=w就过了...

树链剖分的知识:

题目种的具体操作:

ac代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
#define int long long 
#define lc (p<<1)
#define rc (p<<1|1)

int w[N];
vector<int> e[N];
int fa[N],dep[N],sz[N],son[N];
int top[N],id[N],nw[N],cnt;
struct tree {
	int l,r;
	int add,sum;
} tr[4*N];
int n,a[N],c[N];
void dfs1(int u,int father) {
	fa[u]=father,dep[u]=dep[father]+1,sz[u]=1;
	for(int v:e[u]) {
		if(v==father)continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[son[u]]<sz[v])son[u]=v; 
	}
}
void dfs2(int u,int t) {//树链剖分 
	top[u]=t,id[u]=++cnt,nw[cnt]=w[u];
	if(!son[u])return ;
	dfs2(son[u],t);
	for(int v:e[u]) {
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
void pushup(int p) {
	tr[p].sum=tr[lc].sum+tr[rc].sum;
}
void pushdown(int p) {
	if(tr[p].add) {
		tr[lc].sum+=tr[p].add*(tr[lc].r-tr[lc].l+1);
		tr[rc].sum+=tr[p].add*(tr[rc].r-tr[rc].l+1);
		tr[lc].add+=tr[p].add;
		tr[rc].add+=tr[p].add;
		tr[p].add=0;
	}
}
void build(int p,int l,int r) {
	tr[p]= {l,r,0,nw[r]};
	if(l==r)return ;
	int mid=l+r>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(p);
}
void update(int p,int l,int r,int k) {
	if(l<=tr[p].l&&r>=tr[p].r) {
		tr[p].add+=k;
		tr[p].sum+=k*(tr[p].r-tr[p].l+1);
		return ;
	}
	pushdown(p);
	int mid=tr[p].l+tr[p].r>>1;
	if(l<=mid)update(lc,l,r,k);
	if(r>mid)update(rc,l,r,k);
	pushup(p);
}
void update_path(int u,int v,int k) {
	while(top[u]!=top[v]) {
		if(dep[top[u]<dep[top[v]]])swap(u,v);
		update(1,id[top[u]],id[u],k);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v])swap(u,v);
	update(1,id[v],id[u],k);
}

int query(int p,int l,int r) {
	if(l<=tr[p].l&&r>=tr[p].r)return tr[p].sum;
	pushdown(p);
	int mid=tr[p].l+tr[p].r>>1;
	int res=0;
	if(l<=mid)res+=query(lc,l,r);
	if(r>mid)res+=query(rc,l,r);
	return res;
}
int query_path(int u,int v) {
	int res=0;
	while(top[u]!=top[v]) {
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		res+=query(1,id[top[u]],id[u]);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v])swap(u,v);
	res+=query(1,id[v],id[u]);
	return res;
}
int pre[N];
void solve() {
	int n,m;
	cin>>n>>m;

	for(int i=1; i<=n; i++) {
		e[i].clear();
		w[i]=fa[i]=dep[i]=sz[i]=son[i]=0;
		top[i]=id[i]=nw[i]=cnt=a[i]=c[i]=pre[i]=0;
	}
	for(int i=1; i<n; i++) {
		int u,v;
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);

	int cnt=0,cur=0;
	while(m--) {
		int op;
		cin>>op;
		if(op==1) {
			int x,w;
			cin>>x>>w;
			cur+=w-(dep[x]-dep[1]);
			cnt++;

			update_path(1,x,2);
			update_path(1,1,-2);
		} else {
			int x;
			cin>>x;
			int w=query_path(1,x);

			w=w+cur-cnt*(dep[x]-dep[1]);
			if(op==3)cout<<w-pre[x]<<'\n';
			else {
				if(w>0) {
					pre[x]=w;
				}
			}
		}
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	cin>>t;
	while(t--)
		solve();
	return 0;
}

Red Black Grid

哥们有史以来wa的最多的一次,太难写了 

n<=3时打表,

其余情况,分v2,v3,v4,自己悟一下为什么这么分,然后尽量让v4多分一点,v3调节奇偶,剩下的给v2,可以证明1或者2n(n-1)-1时无解,其它情况都是有解的。

ad代码(较丑)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
const int N=1e5+10;

int n, k;
vector<int>ans;
bool vis[1015][1015];
bool fz[1015][1015];
void solve() {
	cin>>n>>k;

	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			vis[i][j]=0;
			fz[i][j]=0;
		}
	}

	ll sum=2*n*(n-1);

	int res;
	if(k>sum||k==1||k==sum-1)cout<<"Impossible\n";
//
	else if(n==1) {
		if(k==0) {
			cout<<"Possible\n";
			cout<<"R\n";
		} else {
			cout<<"Impossible\n";
		}
	} else if(n==2) {
		if(k==0) {
			cout<<"Possible\n";
			cout<<"RR\nRR\n";

		} else if(k==1||k==3) {
			cout<<"Impossible\n";
		} else if(k==2) {
			cout<<"Possible\n";
			cout<<"BB\nRR\n";
		} else if(k==4) {
			cout<<"Possible\n";
			cout<<"RB\nBR\n";
		}
	} else if(n==3) {/


		if(k==1||k==11)cout<<"Impossible\n";
		else {
			cout<<"Possible\n";//
			if(k==0) { /
				cout<<"RRR\nRRR\nRRR\n";
			} else if(k==2) {
				cout<<"RBB\nBBB\nBBB\n";
			} else if(k==3) {
				cout<<"BRB\nBBB\nBBB\n";
			} else if(k==4) {
				cout<<"BBB\nBRB\nBBB\n";
			} else if(k==5) {
				cout<<"RBB\nBBB\nBRB\n";
			} else if(k==6) {
				cout<<"BRB\nBBB\nBRB\n";
			} else if(k==7) {
				cout<<"BRB\nBBB\nRBR\n";
			} else if(k==8) {
				cout<<"RBR\nBBB\nRBR\n";
			} else if(k==9) {
				cout<<"BRB\nRBR\nBBB\n";
			} else if(k==10) {
				cout<<"RBR\nBRB\nRBB\n";
			} else if(k==12) {
				cout<<"RBR\nBRB\nRBR\n";
			}
		}
	}

	else {
		vector<pair<int,int>>v2,v3,v4;
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=n; j++) {
				if((i+j)%2==0) {
					if((i==1||i==n)&&(j==1||j==n)) { 
						v2.push_back({i,j});
					} else if((i==1||i==n)||(j==1||j==n))v3.push_back({i,j});
					else v4.push_back({i,j});
				}
			}
		}
		int c4=0,c2=0,c3=0;
		while(k>=4) {
			c2++;
			k-=2;
		}
		if(k==3) {
			c3++;
			k-=3;
		} else if(k==2) {
			c2++;
			k-=2;
		}



		int s2to3=c2*2/6;
		int pp=((int)v3.size()-c3)/2;
		int t=min(pp,s2to3)*2;
		c3+=t;
		c2-=t*3/2;

		int s2to4=min(c2*2/4,(int)v4.size());
		c4=s2to4;
		c2-=c4*4/2;
		for(int i=0; i<c2; i++) {
			int x=v2[i].first;
			int y=v2[i].second;
			fz[x][y]=1;
		}

		for(int i=0; i<c3; i++) {
			int x=v3[i].first;
			int y=v3[i].second;
			fz[x][y]=1;
		}


		for(int i=0; i<c4; i++) {
			int x=v4[i].first;
			int y=v4[i].second;
			fz[x][y]=1;
		}
		cout<<"Possible\n";
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=n; j++) {
				if(fz[i][j]==1)cout<<"R";
				else cout<<"B";
			}
			cout<<'\n';
		}


	}
}
/*

3 6
3 1
6 4
6 2
9 4

*/

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1000;
	cin>>t;
	while(t--)solve();
	return 0;
}

Sereja and Brackets

2000的线段树题,括号匹配问题,当前区间匹配数等于左右区间各自匹配好的加起来,以及(左区间未匹配好的和右区间未匹配好的)取min,难点在于写法。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define debugs(x,y) cerr<<#x<<" : "<<x<<" "<<#y<<" "<<y<<endl
#define int long long
#define ls ((p<<1))
#define rs ((p<<1)|1)
const int N=1e6+10;

int n,m,a[N];
string str;

struct node {
	int al,ar;
	int sum;
} tr[N<<3];

void pushup(int p) {
	int res=min(tr[ls].al,tr[rs].ar);
	tr[p].sum=tr[ls].sum+tr[rs].sum+res;
	tr[p].al=tr[ls].al+tr[rs].al-res;
	tr[p].ar=tr[ls].ar+tr[rs].ar-res;
}
void build(int p,int l,int r) {
	if(l==r) {
		tr[p].sum=0;
		if(a[l]==1) {
			tr[p].al=1;
		} else tr[p].ar=1;
		return;
	}
	
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(p);
}

node query(int p,int l,int r,int x,int y) {
	if(l>=x&&r<=y) {
		return {tr[p].al,tr[p].ar,tr[p].sum};
	}
	int mid=(l+r)>>1;
	int res=0;
	int resl=0,resr=0;
	node Rl,rr;
	int dd=0;
	if(x<=mid) {
		Rl=query(ls,l,mid,x,y),res+=Rl.sum;
	}
	if(y>mid) {
		rr=query(rs,mid+1,r,x,y),res+=rr.sum;
	}
	if(x<=mid&&y>mid) {
		dd=min(Rl.al,rr.ar);
		resl=Rl.al+rr.al-dd;
		resr=Rl.ar+rr.ar-dd;
		res=res+dd;
	}else if(x<=mid){
		resl=Rl.al;
		resr=Rl.ar;
	}
	else if(y>mid){
		resl=rr.al;
		resr=rr.ar;
	}
	return {resl,resr,res};
}
void solve() {
	cin>>str;
	for(int i=0; i<str.size(); i++) {
		if(str[i]=='(')a[i+1]=1;
		else a[i+1]=-1;
	}

	n=str.size();
	build(1,1,n);
	cin>>m;
//	cout<<tr[1].sum<<endl;
	for(int i=1,x,y; i<=m; i++) {
		cin>>x>>y;
		cout<<query(1,1,n,x,y).sum*2<<'\n';

	}

}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t=1;
//	cin>>t;
	while(t--)solve();
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi Dev for 10.4是指使用Delphi编程语言进行开发的工具版本。Delphi是一种强大的集成开发环境(IDE),允许开发人员创建跨平台的移动应用程序、桌面应用程序和Web应用程序。 Delphi Dev for 10.4是Embarcadero Technologies公司开发的最新版本,它提供了许多强大的功能和工具,帮助开发人员更高效地构建应用程序。 首先,Delphi Dev for 10.4提供了一套丰富的组件库,包括数据访问、用户界面、网络通信等方面的组件。这些组件可以大大加快开发进程,减少重复工作,并提供了一致的用户体验。 其次,Delphi Dev for 10.4支持多平台开发。开发人员可以使用Delphi开发Android、iOS、Windows和macOS等平台的应用程序。这使得开发人员能够通过一次编码实现应用程序在多个平台上的部署,提高了开发效率。 此外,Delphi Dev for 10.4还提供了一套强大的IDE,用于代码编辑、调试和测试。它包括代码自动完成、语法高亮、实时错误检查等功能,帮助开发人员编写高质量的代码。此外,IDE还整合了调试器,使开发人员能够轻松地调试和定位错误。 最后,Delphi Dev for 10.4还提供了丰富的文档和学习资源,帮助新手上手并提高开发人员的技能。开发人员可以参考官方文档、示例代码和在线社区,与其他Delphi开发人员交流和分享经验。 总而言之,Delphi Dev for 10.4是一个功能强大、易于使用的开发工具,提供了丰富的功能和工具,使开发人员能够更高效地构建应用程序。无论是初学者还是经验丰富的开发人员,都可以通过Delphi Dev for 10.4来实现他们的开发目标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值