洛谷十月月賽2T1瀏覽器P4932
阿新 • • 發佈:2018-11-02
傳送門
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; }