很废,做了一题。
第二题超时了,删掉一个0就给多了,血亏
做题地址:Codeforces Round #735 Div.2
题目:
让连续区间内,最大值和最小值的乘积最大
解决:
可以看出相邻两个的最大乘积就是答案。
分析:
假设最优答案至少是长度为3的连续区间,那么,长度为3的连续区间内,有一个最大值,一个最小值,和一个中等值,那么,相邻两个的乘积要么最大,要么次大,但一定可以覆盖长度为3的区间的答案,甚至更优。
代码:
int n;
LL a[N];
void work()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
scanf("%lld", &a[i]);
LL ans = 0;
for (int i = 2; i <= n; i ++ )
ans = max(ans, a[i] * a[i - 1]);
printf("%lld\n", ans);
}
题目:
给定一个长度为n的序列,输出i * j - k * (a[i] | a[j])
的最大值。
解决:
我们知道n是1e5大小的数字,k是个小于100的数字,而且a[i] | a[j]
最大不过2 * n
大小,所以,当n比较小的时候,可以暴力做。当n大的时候可以只枚举后100个就可以了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma GCC optimize(2)
//#pragma GCC optimize(3, "Ofast", "inline")
using namespace std;
#define ios ios::sync_with_stdio(false) , cin.tie(0),cout.tie(0)
#define rep(i, n) for (int i = 0; i < n; ++ i)
#define x first
#define y second
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 300010, INF = 0x3f3f3f3f, mod = 1e9 + 7, base = 131;
const double eps = 1e-6, PI = acos(-1);
LL n, k;
LL a[N];
void work()
{
memset(a, 0, sizeof a);
cin >> n >> k;
for (int i = 1; i <= n; i ++ )
scanf("%lld", &a[i]);
if (n <= 1000)
{
LL ans = -2e14;
for (LL i = 1; i <= n - 1; i ++ )
for (LL j = i + 1; j <= n; j ++ )
ans = max(ans, i * j - k * (a[i] | a[j]));
printf("%lld\n", ans);
}
else
{
LL ans = -2e14;
for (LL j = n - 100; j <= n; j ++ )
for (LL i = 1; i < j; i ++ )
ans = max(ans, j * i - k * (a[i] | a[j]));
printf("%lld\n", ans);
}
}
int main(void)
{
//ios;
int T = 1;
cin >> T;
while (T -- )
{
work();
}
return 0;
}
题目:给定n和m,都是1e9大的数字,问{n ^ 0 , n ^ 1, …, n ^ m}中,最小的没有出现的非负整数为多少。
解决:
首先,我们需要了解一个性质:
a ^ x = y, 等价于 a ^ y = x
明白这个性质后,我们再观察{n ^ 0 , n ^ 1, …, n ^ m}。
假定n ^ x = k,我们要找的就是不在序列中出现过的最小非负整数k。
那么,我们交换x和k,n ^ k = x,可以发现,所有的k值的集合,一定满足,n ^ k 的值x是连续的从0到n。一定不满足n ^ k > m。
所以,我们需要找到的就是n ^ k > m中,最小的k。如果不理解的话,可以换一个角度来考虑。
我们依次考虑k = 0,k = 1,k = 2,k = …。如果n ^ k 在0~m的范围内,那么,一定存在n ^ (0 ~ m) = k。这样的k都是合法的,那么直到第一个k使得n ^ k > m。这时,就不存在{0, 1, … m}和n异或得到这个k。那么,这个k就是我们的合法方案。
不知道这样说清不清楚哎QAQ
#include
using namespace std;
const int N = 100010;
int n, m;
void work()
{
cin >> n >> m;
m ++;
//也可以先特判下n > m直接为0
int ans = 0;
for (int i = 30; i >= 0 && n < m; i -- )
{
if ((n >> i & 1) && (m >> i & 1)) continue;
//我们可以n = n ^ k。当n
if ((m >> i & 1) && !(n >> i & 1)) ans |= 1 << i, n |= 1 << i;
}
cout << ans << endl;
return;
}
int main()
{
int T;
cin >> T;
while (T -- )
{
work();
}
return 0;
}
题目:
构造一个1e5的字符串,使得字符串S的每个子串都只出现奇数次。
解决:
假设这里有k个a,那么它的字串个数为a k, aa k - 1, aaa k - 2, …
如果有k-1个a,那么它的子串个数为a k - 1, aa k - 2, aaa k - 3 …
两者加起来,可得: x + (x - 1) = 2 * x - 1是个奇数
所以,我们可以这么构造
现在我们可以将前n / 2个构造为a,将后n / 2 - 1个构造也为a,中间剩下的用b~c来构造,如果n是偶数,用b,如果是偶数用bc
#include
using namespace std;
int n;
void work()
{
cin >> n;
if (n <= 3)
{
if (n == 1) cout << "a" << endl;
else if (n == 2) cout << "ab" << endl;
else if (n == 3) cout << "abc" << endl;
return;
}
string s(n / 2, 'a');
string t(n / 2 - 1, 'a');
if (n & 1) cout << s << "bc" << t << endl;
else cout << s << "b" << t << endl;
}
int main()
{
int T; cin >> T;
while (T -- )
{
work();
}
return 0;
}