第一题:
小红拿到了一个数组,她定义f(i)为:将第i个元素翻倍后,数组所有元素的按位异或的值。
现在小红希望你求出f(1)到f(n)的值。
请注意,每次求f(i)后,原数组的元素不会真正翻倍。
输入描述
第一行输入一个正整数n,代表小红拿到的数组长度。
第二行输入n个正整数a_i,代表数组的元素。
输出描述
输出n行,每行输出一个整数,代表将第i个元素翻倍后,所有元素按位异或的值。
示例 1
输入
3
1 3 1
输出
0
6
0
说明
第一个元素翻倍后,数组为[2,3,1],所有元素异或等于0。
第二个元素翻倍后,数组为[1,6,1],所有元素异或等于6。
第三个元素翻倍后,数组为[1,3,2],所有元素异或等于0。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
vector<int>arr(n);
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
int cnt=arr[0];
for(int i=1;i<n;i++)
cnt=cnt^arr[i];
for(int i=0;i<n;i++)
{
cnt=cnt^arr[i];
arr[i]*=2;
cnt=cnt^arr[i];
cout<<cnt<<endl;
cnt=cnt^arr[i];
arr[i]/=2;
cnt=cnt^arr[i];
}
}
第一题简单成功ac,利用一个值异或两次结果不变的性质。若暴力判断只能通过三分之一的用例。
第二题:
小红拿到了一个正整数x,她希望在区间[l,r]中选择一个正整数y,满足x*y是完全平方数。小红想知道有多少种选择方案?
共有q次询问。
输入描述
第一行输入两个正整数q,x,代表询问次数和小红拿到的正整数。
接下来的q行,每行输入两个正整数l,r,代表一次询问。
输出描述
输出q行,每行输出一个整数,代表询问的答案。
示例 1
输入
1 2
6 9
输出
1
说明
只有选择8这一个方案。
#include <bits/stdc++.h>
using namespace std;
bool issquare(long long x)
{
if(x==1||x==0)return true;;
long long left=0,right=x/2,mid=left+((right-left)>>1);
while(left<=right)
{
if(mid==0)return false;
if(mid==x/mid&&(x%mid==0))
return true;
else if(mid>x/mid)
{
right=mid-1;
mid=left+((right-left)>>1);
}
else
{
left=mid+1;
mid=left+((right-left)>>1);
}
}
return false;
}
void work(int &cur,int &x)
{
int temp=min(cur,x);
temp/=2;
for(int i=2;i<temp;i++)
{
if(cur%i==0&&x%i==0)
{
cur/=i;
x/=i;
}
}
}
int main() {
long long q,x;
cin>>q>>x;
while(q--)
{
long long l,r;
cin>>l>>r;
int res=0;
for(long long i=l;i<=r;i++)
{
int temp1=x,temp2=i;
work(temp1,temp2);
if(issquare(temp1*temp2))
res++;
// if(i==x)
// {
// res++;
// continue;
// }
// else if(i>x)
// {
// if(i%x==0)
// {
// if(issquare(i/x))
// res++;
// }
// else
// {
// if(issquare(i*x))res++;
// }
// }
// else
// {
// if(x%i==0)
// {
// if(issquare(x/i))
// res++;
// }
// else
// {
// if(issquare(i*x))res++;
// }
// }
}
cout<<res<<endl;
}
}
第二题应该只通过了16%。
第三题:
小红养了一些实验用的小鼠,其中一些是黑色的,一些是白色的,小鼠们住在一棵树上,每只小鼠都在这棵树的一个节点上。
现在小红想重新安排每只小鼠的位置,然后在一条边上建一面墙,使得所有黑鼠和白鼠都被这面墙分开,小红想知道共有多少种建墙的方案。
输入描述
第一行输入一个整数 n(1 \leq n \leq 10^5) 表示小鼠数量。
第二行输入一个长度为 n 的字符串 s 表示小鼠的颜色,第 i 个节点上小鼠的颜色为 s_i ,若 s_i 为 'B' 表示小鼠的颜色为黑色,若 s_i 为 'W' 则表示小鼠的颜色为白色。
接下来 n-1 行,每行输入两个整数 u,v(1 \leq u,v \leq n) 表示树上存在一个 u 到 v 的边。
输出描述
输出一个整数表示答案。
示例 1
收起
输入
3
BWB
1 2
2 3
输出
2
说明
总共有1个小白鼠。
方案1:在1-2之间建一面墙,将白鼠安排在第1个节点,将黑鼠安排在第2、3个节点。
方案2:在2-3之间建一面墙,将白鼠安排在第3个节点,将黑鼠安排在第1、2个节点。
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>>arr;
vector<int>cnt;
int dfs(int x,int fa)
{
if(cnt[x]!=-1)return cnt[x];
int res=0;
if(arr[x].size()==1&&x!=1)
res=1;
else
{
for(int i=0;i<arr[x].size();i++)
{
if(arr[x][i]==fa)continue;
res+=dfs(arr[x][i],x);
}
res+=1;
}
cnt[x]=res;
return res;
}
int main() {
int n;
cin>>n;
string str;
cin>>str;
cnt.resize(n+1,-1);
arr.resize(n+1);
for(int i=0;i<n-1;i++)
{
int u,v;
cin>>u>>v;
arr[u].push_back(v);
arr[v].push_back(u);
}
int black=0,white=0;
for(int i=0;i<n;i++)
{
if(str[i]=='W')white++;
}
black=n-white;
int res=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<arr[i].size();j++)
{
if(dfs(arr[i][j],i)==black||dfs(arr[i][j],i)==white)
res++;
}
}
cout<<res;
}
第三题通过了三分之一。