洛谷十月月赛2T1浏览器P4932

传送门

https://www.luogu.org/problemnew/show/P4932

题面

题目描述
__stdcall给了你n个点,第i个点有权值x[i],对于两个点u和v,如果x[u] xor x[v]的结果在二进制表示下有奇数个1,那么在u和v之间连接一个Edge,现在__stdcall想让你求出一共有多少个Edge。
如果你没能成功完成任务,那么__stdcall会让你痛苦一下,你这个测试点就没分了。
输入输出格式
输入格式:
一行六个整数,n,a,b,c,d,x[0]。
n是点的个数,每个点的权值需要用如下的方式生成。
你需要使用a,b,c,d和x[0]生成一个数组x,生成方式是这样的。

在这里插入图片描述
x[i]就是第i个点的权值,点的标号是1到n。

输出格式:
输出一个整数,表示一共有多少个Edge。**
在这里插入图片描述

思路

在这里插入图片描述

O(nlogn)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int read()
{
	char ch=' ';
	int f=1;int x=0;
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
	    x=x*10+ch-'0';ch=getchar();
	}
	return x*f;
}
const int N=1e7+100;
int x[N];
int n,a,b,c,d;
int calc(int x)
{
	ll ret=0;
	ll y=1ll*a*x%d*x%d;
	ret+=y;
	y=1ll*b*x%d;
	ret=(ret+y)%d;
	ret=(ret+c)%d;
	return ret;
}
int cnt(int x)
{
	int ret=0;
	while(x)
	{
		if(x&1)
		ret++;
		x=x>>1;
	}
	return ret;
}
int main()
{
	n=read();a=read();b=read();c=read();d=read();
	x[0]=read();
	int i,j;
	for(i=1;i<=n;i++)
	{
		x[i]=calc(x[i-1]);
	}
	int odd=0,even=0;
	for(i=1;i<=n;i++)
	{
		int popcnt=cnt(x[i]);
		if(popcnt%2==1)
		{
			odd++;
		}
		else
		{
			even++;
		}
	}
	printf("%lld\n",1ll*odd*even);
	return 0;
}

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int read()
{
	char ch=' ';
	int f=1;int x=0;
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
	    x=x*10+ch-'0';ch=getchar();
	}
	return x*f;
}
const int N=1e7+100;
int x[N];
int n,a,b,c,d;
int calc(int x)
{
	ll ret=0;
	ll y=1ll*a*x%d*x%d;
	ret+=y;
	y=1ll*b*x%d;
	ret=(ret+y)%d;
	ret=(ret+c)%d;
	return ret;
}
int work(int x)
{
	int ret=0;
	while(x)
	{
		if(x&1)
		ret++;
		x=x>>1;
	}
	return ret;
}
const int M=1<<18;
int cnt[M+10];
void prework()
{
	for(int i=0;i<M;i++)
	{
		cnt[i]=work(i);
	}
}
int check(int x)
{
	return cnt[x&(M-1)]+cnt[x>>18];
}
int main()
{
	n=read();a=read();b=read();c=read();d=read();
	x[0]=read();
	int i,j;
	for(i=1;i<=n;i++)
	{
		x[i]=calc(x[i-1]);
	}
	int odd=0,even=0;
	prework(); 
	for(i=1;i<=n;i++)
	{
		int popcnt=check(x[i]);
		if(popcnt%2==1)
		{
			odd++;
		}
		else
		{
			even++;
		}
	}
	printf("%lld\n",1ll*odd*even);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42110318/article/details/83267896
今日推荐