CF1798

CF1798

随的div2构造场 真是想不出来

Showstopper

乱搞过了

我们钦定 b[n]a[n] 小 那么我们如果 b[i]>b[n] 的话 那么别无他法 只能换一下 如果换了也不行 直接判无解即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
const int N = 100 + 5;
const int inf = 0x3f3f3f3f;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , a[N] , b[N] , tmp[2] , maxx;

signed main ()
{
	ios::sync_with_stdio(false);
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		n = read();
		generate ( a + 1 , a + n + 1 , read );
		generate ( b + 1 , b + n + 1 , read );
		if ( a[n] < b[n] ) swap ( a[n] , b[n] );
		for ( int i = 1 ; i <= n - 1 ; i ++ )
		{
			tmp[0] = a[i] , tmp[1] = b[i];
			if ( min ( tmp[0] , tmp[1] ) > b[n] ) { cout << "No" << endl; goto flg; }
			else if ( tmp[1] > b[n] ) swap ( a[i] , b[i] );
		}
		maxx = -inf;
		for ( int i = 1 ; i <= n ; i ++ ) maxx = max ( maxx , a[i] );
		if ( maxx != a[n] ) { cout << "No" << endl; goto flg; }
		cout << "Yes" << endl;
		flg:;
	}
	return 0;
}

Three Sevens

简单构造题 发现对于每一个人 只有最后一次买彩票中奖才有用

那么我们直接开 lst[i] 数组表示 i 人最后一次买彩票的场次 我们再开一个数组 cnt[i] 表示 i 天对应的中奖人编号

那么我们扫一遍值域为 cnt 数组赋值 最后扫一遍 cnt 数组判断无解或者输出方案即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
const int N = 5e4 + 5;
const int inf = 0x3f3f3f3f;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n[N] , m , lst[N] , vis[N];

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		memset ( vis , 0 , sizeof vis );
		memset ( lst , 0 , sizeof lst );
		m = read();
		for ( int i = 1 ; i <= m ; i ++ )
		{
			n[i] = read();
			for ( int j = 1 ; j <= n[i] ; j ++ ) lst[read()] = i;
		}
		for ( int i = 1 ; i <= 50000 ; i ++ ) if ( lst[i] ) vis[lst[i]] = i;
		int flag = 1;
		for ( int i = 1 ; i <= m ; i ++ ) if ( !vis[i] ) { flag = 0; break; }
		if ( !flag ) cout << -1 << endl;
		else 
		{
			for ( int i = 1 ; i <= m ; i ++ ) cout << vis[i] << ' ';
			cout << endl;
		}
    }
	return 0;
}

Candy Store

想不到www

假设一个标签 tag 概括了 lr 种糖果的标签 则我们设 tag=clr

ci=di×bi

blrtag

lcm(bl,bl+1br)tag

diai

ciai×bi

taggcd(al×bl,al+1×bl+1ar×br)

lcm(bl,bl+1br)gcd(ai×bi,ai+1×bi+1ar×br)

所以只要判断当前 gcd 是否能被 lcm 整除即可 如果不能 将 gcd 更新成 ai×bi lcm 更新成 bi

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
#define int long long 
const int N = 2e5 + 5;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , a[N] , b[N] , ans;

int gcd ( int a , int b )
{
	if ( a % b == 0 ) return b;
	return gcd ( b , a % b );
}
int lcm ( int a , int b )
{
	return a * b / gcd ( a , b );
}

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		n = read();
		ans = 1;
		for ( int i = 1 ; i <= n ; i ++ ) a[i] = read() , b[i] = read();
		int gcdd = a[1] * b[1] , lcmm = b[1];
		for ( int i = 2 ; i <= n ; i ++ )
		{
			gcdd = gcd ( gcdd , a[i] * b[i] ) , lcmm = lcm ( lcmm , b[i] );
			if ( gcdd % lcmm ) lcmm = b[i] , gcdd = a[i] * b[i] , ++ ans;
		}
		cout << ans << endl;
	}
	return 0;
}

Shocking Arrangement

首先判断特例:如果全是 0 显然无解

对于其余的情况 我们维护新数列的前缀和 如果这个前缀和大于 0 那么我们在负数中选一个数加进序列中 如果前缀和小于等于 0 那么塞进去一个正数即可

这样对于每一个前缀和 我们都能保证它的取值范围在 [mina[i],maxa[i]] 中间 那么任意两个前缀和相减的绝对值最大值就一定在 maxa[i]mina[i] 之内 所以符合条件

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
#define int long long 
const int N = 3e5 + 5;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , a[N] , b[N] , ans , flag , sum;
vector<int> zheng , fu;

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		flag = 0 , sum = 0;
		n = read();
		zheng.clear() , fu.clear();
		for ( int i = 1 ; i <= n ; i ++ ) flag |= ( a[i] = read() ) , a[i] >= 0 ? zheng.eb(a[i]) : fu.eb(a[i]);
		if ( !flag ) { cout << "No" << endl; continue; }
		cout << "Yes" << endl;
		cout << zheng[zheng.size()-1] << ' ';
		sum = zheng[zheng.size()-1];
		zheng.pop_back();
		for ( int i = 2 ; i <= n ; i ++ )
			if ( sum > 0 ) cout << fu[fu.size()-1] << ' ' , sum += fu[fu.size()-1] , fu.pop_back();
			else cout << zheng[zheng.size()-1] << ' ' , sum += zheng[zheng.size()-1] , zheng.pop_back();
		cout << endl;
	}
	return 0;
}

Multitest Generator

显然 操作数最多为两次 因为我们对于任意序列 [1,n] 都可以通过将 a1 固定为 1 而将 a2 改为 n2 来满足条件

对于 0 次操作 我们可以记录 f[i] 数组表示以 i 为末尾的后缀能构成的 test 个数

那么转移方程不难得到:

fi={1,ai=(ni+1)10,i+ai>norfi+ai+1=0fi+ai+1+1,otherwise

i 位答案为 0 的充要条件就是 fi+10ai=fi+1

如果答案不为 0 考虑两种情况:

  1. fi+10,但是 aifi+1
  2. fi+1=0

对于第一种情况,令 aifi+1 即可,操作数为 1

对于第二种情况,如果想要答案为 1 显然需要对 i+1 的后缀中的某一个数进行修改 使修改后 i+1 的后缀能构成 aitest

gi 表示在 i 的后缀中进行一次修改后 能得到的最多 test

这个修改有两种情况:

  1. 修改 ai。这意味着我们可以随意改变第一个 test 的长度,也就是这第一个 test 可以接在后面的任意一个状态的前面,这种情况能得到的最大值为 maxj=i+1nfj+1
  2. 不修改 ai。因为 ai+1ai+ai 之间的数会被 ai 所在的 test 所包含,所以只有修改 i+ai+1 的后缀中的某个数才能有贡献。因此这种情况能得到的最大值为 gi+ai+1+1

那么 “ 对 i+1 的后缀中的某一个数进行修改后,i+1 的后缀能构成 aitest ” 的充要条件就是 gi+1ai 之所以是大于等于号 是因为我们可以将前面的一次 1 操作或者 2 操作改为修改 ai 来吃掉一些 test

剩下的情况答案就是 2

清数组要清到 n+1 (?)

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define pii pair<int,int>
#define fi first
#define se second
#define getchar() cin.get()
const int N = 3e5 + 5;

int read()
{
	int f = 1 , x = 0;
	char ch = getchar();
	while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
	while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
	return x * f;
}

int n , a[N] , ans[N] , f[N] , g[N] , fmaxx[N];

void init()
{
	for ( int i = 1 ; i <= n + 1 ; i ++ ) f[i] = g[i] = ans[i] = fmaxx[i] = 0;
}

/*
3
7
3 1 3 1 2 1 1
4
1 2 1 7
4
2 7 1 1
*/

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	int T = read();
	while ( T -- )
	{
		n = read();
		init();
		for ( int i = 1 ; i <= n ; i ++ ) a[i] = read();
		for ( int i = n ; i >= 2 ; i -- )
		{
			if ( i + a[i] == n ) f[i] = 1;
			else if ( i + a[i] < n && f[i+a[i]+1] ) f[i] = f[i+a[i]+1] + 1;
			fmaxx[i] = max ( f[i] , fmaxx[i+1] );
			if ( i + a[i] >= n ) g[i] = fmaxx[i+1] + 1;
			else g[i] = max ( fmaxx[i+1] , g[i+a[i]+1] ) + 1;
		}
		for ( int i = n - 1 ; i ; i -- )
		{
			if ( f[i+1] ) ans[i] = ( a[i] != f[i+1] );
			else if ( g[i+1] >= a[i] ) ans[i] = 1;
			else ans[i] = 2;
		}
		for ( int i = 1 ; i <= n - 1 ; i ++ ) cout << ans[i] << ' ';
		cout << endl;
	}
	return 0;
}
posted @   Echo_Long  阅读(525)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示