2022-06-05每日刷题打卡

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.

img

问题解析:

这题是说,有一个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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值