2022-06-05每日刷题打卡
HUSTPC 2022
Problem - M - Codeforces
Walk_alone has a sequence a of length n. He can do the following operations for arbitrary times (possibly zero):
Select an index x and an integer y (1≤x≤n,0≤y<2^30 );
For all index i such that i≠x, change ai to ai⊕y, where ⊕ denotes bitwise XOR.
Note that Walk_alone can select different y in different operations.
Now he wants to know if he can change all numbers in the sequence to 0.
Input
The first line contains a integers n (1≤n≤10^5 ), the length of sequence a.
The next line contains n integers a1,a2,…,an (0≤ai<2^30 ), indicating the elements in a.
Output
Print “YES” (without quotes) if Walk_alone can change all numbers in the sequence to 0, otherwise print “NO”.
Examples
input
5
5 4 2 1 2
output
YES
问题解析
这题是说,给你一个数组,每次可以选一个数y和一个下标i,把除这个下标i外的元素都用y进行一次异或运算。问有没有可能把这个数组变成一个全是0的情况。
这是一个结论题,先说结论:当数组长度是偶数时,必是YES;如果是奇数就看数组所有数异或后是不是0,如果是就是YES,反之是NO。接下来来推结论:
我们可以先通过n次操作把数组全变成相同的一个数,我们下标从i=0取到i=n-1,y就选arr[i]。为什么这样可以使得数组变成相同的一个数?因为这样就相当于使得数组中的每一个数,将除了自己以外的元素都进行了异或运算。这样得到的一个数就是arr[0]arr[1]arr[2]……^arr[n-1]。这样每个数都会是相同的,而且这个数就是这个式子得到的结果。
异或运算有两个性质:异或自己就相当于把自己变成0;异或同一个数两次就相当于没异或。
我们再取下标i=0到i=n-1进行操作,y就取arr[0]arr[1]arr[2]……^arr[n-1],即现在数组都相同的那个数,这样会使得数组每个元素进行了n-1次运算,当n-1是偶数时,相当于没异或,数组的值不变;当n-1是奇数时,相当于每个元素都异或了一下自身,变成0.
所以当n-1是奇数时,我们必然能把数组变成全是0;而n-1是偶数时,数组的值不会改变,除非arr[0]arr[1]arr[2]……^arr[n-1]等于0,这样在一开始把数组变成相同的时候数组就全是0了,其余情况都不能把数组变成0.
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 550;
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n;
cin >> n;
if (n % 2 == 0)
{
cout << "YES";
return 0;
}
int x, res = 0;
for (int i = 0; i < n; i++)
{
cin >> x;
res ^= x;
}
if (res == 0)cout << "YES";
else cout << "NO";
return 0;
}
Problem - K - Codeforces
Walk_alone has a 500×500 square grid in a plane. The lower-left corner of the grid locates at (0,0), and all squares in it are of size 1×1.
There are n segments in the grid, the i-th of which connecting point (xi,yi) and (xi−1,yi−1). Now you are required to find out the number of triangles in the grid.
Input
The first line contains an integer n (1≤n≤250000), the number of segments in the grid.
The i-th of the next n lines contains two integers xi and yi (1≤xi,yi≤500) as described above. It is guaranteed that (xi,yi)≠(xj,yj) for all i≠j.
Output
Output an integer representing the number of triangles.
Examples
input
3
1 1
2 2
3 1
output
8
Note
The figure below illustrates the first example.
问题解析:
这题是说,有一个500*500的方格,给你一些点的坐标(x,y),这些点会和(x-1,y-1)连成一条线,问这个方格里会有多少三角形。
首先可以通过提示的图中看出,每一条对角线,可以得到两个三角形(将一个正方形分出来两个三角形)。我们基础的线长度可以把一个1*1的正方形分成两个三角形,如果我们的对角线可以和其它格子的对角线相连,就可以分开一个更大的三角形,比如图中左边的情况,将一个2 *2的正方形变成了两个三角形。
我们可以先根据点的数量,知道至少会有2*n个三角形。然后根据点的坐标,看有没有能够合成一起的对角线,如果有x条对角线合在一起,根据等差数列求和我们可以推出可以额外得到n *(n-1)个三角形。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#define endl '\n'
#define int ll
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 550;
int mymap[N][N], cnt[N][N];
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n;
cin >> n;
vector<PII>v(n);
int res = 2 * n;
for (int i = 0; i < n; i++)
{
cin >> v[i].first >> v[i].second;
mymap[v[i].first][v[i].second] = 1;
}
sort(v.begin(), v.end());
for (auto i : v)
{
int a = i.first, b = i.second;
if (mymap[a][b] == 1)
{
mymap[a][b] = 0;
int ans = 1;
while (mymap[a + 1][b + 1])
{
a++;
b++;
mymap[a][b] = 0;
ans++;
}
res += ans * (ans - 1);
}
}
cout << res << endl;
return 0;
}