2022 浙大城市学院 新生赛 补题

14 篇文章 0 订阅

题目

K
题意: 给定n次位运算,包括&、|、^.给定q次询问,每次可以选择[0,r]中的任意整数x,令x经过这n次位运算最大,输出选择的x.
思路: 贪心。比较套路的题,这n次位运算是独立的,可以对于每一位提前预处理出来,以0和1为起点能否变成1. 然后对于每次查询,从高位到低位处理,如果0能变成1直接这一位填0,如果1才能变成1在满足限制的前提下这一位填1,二进制特性,这一位选1比后边所有位都选1更优。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int n,m,k,T;
struct node{
	int op;
	int x;
}a[N];
bool vis[33][2];
void solve()
{
	int q;
	scanf("%d%d",&n,&q);
	for(int i=0;i<n;++i)
	{
		int op,x;
		scanf("%d%d",&op,&x);
		a[i] = {op,x};
	}
	for(int k=29;k>=0;--k) //ö�ٵ�kλΪ0����1����� 
	{
		for(int i=0;i<=1;++i) //0��1 
		{
			int now = 0;
			if(i==0) now = 0;
			else now = (1<<k);
			for(int j=0;j<n;++j)
			{
				int op = a[j].op;
				int x = a[j].x;
				if(x>>k&1) x = (1<<k);
				else x = 0;
				if(op==1) now &= x;
				else if(op==2) now |= x;
				else now ^= x;
			}
			if(now==(1<<k)) vis[k][i] = 1;
		}
	}
	while(q--)
	{
		int mx; scanf("%d",&mx);
		int ans = 0;
		int cost = 0;
		for(int i=29;i>=0;--i)
		{
			if(vis[i][0])
			{
//				cout<<i<<"??\n";
				ans = ( ans | (1<<i) );
			}
			else if(vis[i][1])
			{
				int tmp = (1<<i);
				if(cost+tmp<=mx) cost = cost + tmp;
			}
		}
		printf("%d\n",cost);
	}
}
signed main(void)
{
	solve();
	return 0;
}

G
题意: 给定n层的树,第i层有i个叶子,类似数字三角形。起始所有叶子都是红的,有若干个叶子被染黑了。所有染黑的叶子的左右两儿子都会黑,如果相邻两个叶子都黑,他们上边的叶子也会黑。
思路: 如果某个叶子染黑,他可以一直扩展到第n层。最后的结果会是若干个互不相交的三角形,每个三角形的贡献是n*(n+1)/2。在第n层用差分维护,即可获得对应的三角形,统计答案。记得关流,不然输入就T了,麻。
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int b[N];
int n,m,k,T;
void solve()
{
	cin>>n>>k;
	while(k--)
	{
		int i,j; cin>>i>>j;
		int l = j;
		int r = j+n-i;
		b[l]++,b[r+1]--;
	}
	for(int i=1;i<=n;++i) b[i] += b[i-1];
	int now = 0; ll ans = 0;
	for(int i=1;i<=n;++i)
	{
//		cout<<i<<":"<<b[i]<<"\n";
		if(b[i]>0) now++;
		else ans += 1ll*now*(now+1)/2,now = 0;
	}
	if(now) ans += 1ll*now*(now+1)/2,now = 0;
	cout<<ans;
}
signed main(void)
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	solve();
	return 0;
}

I
题意: 给定x、y、z,x和y都有a个1、b个0,z有c个0. 满足y<=x,z=x-y。构造合法的x、y.
思路:
1 … 0
0 … 1
其余的1分别对应,做差的时候就可以忽略了。
令n=a+b,这样一做差就是n-1个1了。之后每次可以把最后的0和1都提前,每提前1位就减少1个1.
所以0到n-1个1都能变。
PS: 注意特判a、b、c为0的特殊情况
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
int n,m,k,T;
void solve()
{
	int a,b,c; cin>>a>>b>>c;
	n = a+b;
	if(c==0)
	{
		for(int i=0;i<a;++i) cout<<1; for(int i=0;i<b;++i) cout<<0;
		cout<<"\n"; 
		for(int i=0;i<a;++i) cout<<1; for(int i=0;i<b;++i) cout<<0;
		return ;
	}
	if(a==0||b==0)
	{
		cout<<-1; return ;
	}
	if(c<=n-1)
	{
		vector<int> va(n),vb(n);
		va[0] = 1; 
		vb[0] = 0;
//		int wh = (n-1)-c; //ƫ��.wh=0˵������Ӧ��λ��Ϊ���һλ��wh=1˵���ڵ�����2λ 
		int idx = c;
		va[idx] = 0,vb[idx] = 1;
		int cnt1 = a-1,cnt0 = b-1;
		for(int i=1;i<n;++i)
		{
			if(i==idx) continue;
			if(cnt1) 
			{
				cnt1--; va[i] = vb[i] = 1;
				continue;
			}
			if(cnt0)
			{
				cnt0--; va[i] = vb[i] = 0;
				continue;
			}
		}
		for(int i=0;i<n;++i) cout<<va[i];
		cout<<"\n";
		for(int i=0;i<n;++i) cout<<vb[i];
	}
	else cout<<-1;
}
signed main(void)
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值