今天嫖来的两道题

C. Even Subarrays
题目链接
感觉还是写点题状态比较正常一点
这个题我只能想到 n 2 n^2 n2复杂度的,但是后来想到尺取法,又不知道该咋尺取,还好可以随便看大佬的代码
思路是这样的,他们的复杂度都是 n n n了,首先处理出一个异或和的前缀数组,然后,利用这个前缀和数组往前找,就是从前向后遍历这个前缀和数组,然后把他犯规的那个异或和给减下去,容易想到奇数个因子,显然就是平方数嘛,然后你就和平方数异或呗,如果异或的这个结果在你刚才遍历过的前缀和当中你就把他给减下去,当然需要一些边界的问题
代码:

#include
#include
#include
using namespace std;
typedef long long ll;
const int length = 2e5 + 5;
int nums[length];
int main(void)
{
	int t;
	scanf_s("%d", &t);
	for (int i = 0; i < t; i++)
	{
		//memset(t1, 0, sizeof(t1));
		
		int n;
		scanf_s("%d", &n);
		vector<int> t1(n*4+1, 0);
		for (int i = 1; i <= n; i++)
		{
			int x;
			scanf_s("%d", &x);
			nums[i] = nums[i - 1] ^ x;
		}
		ll ans = (ll)n * (n + 1) / 2;
		t1[0] = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 0; j*j <= n*2 ; j++)
			{
				int tmp = nums[i] ^ (j*j);
				ans -= t1[tmp];
			}
			t1[nums[i]]++;
		}
		printf("%lld\n", ans);
	}
}

这块学到了一些,就是尽量少开全局变量,如果空间小的话,就在局部区声明即可。如果初始化一次1e5是很耗时的。
D. Valiant’s New Map
这个题我还是想到的尺取法,这个题是可以尺取的,但是之后咋做我就又不知道了,只能提取出来一堆区间,如果能把这些区间用一种数据结构给组织起来的话就好了嘤,但是我不知道应该用啥数据结构给组织起来,于是额,我就去看了大佬的代码,发现他们是一种暴力的遍历,但是好像又不太暴力,纯暴力的解法就是扩大正方形边长,然后遍历那个正方形,那么这样的话,正方形边长的复杂度是 O ( n 1 / 2 ) O(n^{1/2}) O(n1/2),然后取i,j位置是 O ( n m ) O(nm) O(nm),然后再遍历正方形复杂度是 O ( n 2 ) O(n^2) O(n2),起码得五重循环吧,,这样
但是我看的代码是:每次都取邻近小正方形的值,然后每次取得正方形都扩大一点,拿第一个点来说,第一次是左的11正方形,第二次是左的22正方形,依次扩大,这样的话才能把这个正方形给扩大。
代码:

#include
#include
#include
#include
#include
#include
#define min(a,b) ((a<b)?a:b)
using namespace std;
 
int main(void)
{
	int t;
	scanf_s("%d", &t);
	for (int i = 0; i < t; i++)
	{
		int n, m;
		scanf_s("%d%d", &n, &m);
		vector<vector<int>> graph(n + 5, vector<int>(m + 5));
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				scanf_s("%d", &graph[i][j]);
			}
		}
		int ans = 1;
		for (int k = 1; k < n; k++)
		{
			for (int i = 0; i < n-k; i++)
			{
				for (int j = 0; j < m-k; j++)
				{
					 
					graph[i][j] = min(graph[i][j],min(graph[i + 1][j],min(graph[i][j + 1], graph[i + 1][j + 1]) ));
					if (graph[i][j] >= k + 1)
					{
						ans = k + 1;
					}
				}
			}
		}
		printf("%d\n", ans);
	}
}

这个复杂度没太算明白,但是不超时就听离奇的
还是把变量放在局部区

你可能感兴趣的:(算法题目,c++,算法,图论)