题目大意:给出n个数,这n个数上的pi位如果为1,则其他数可为1或0,但如果这n个数上pi位都不为1,则其他数pi位一定不为1
思路:二进制分解数x,记表示第x位上是否有数,则对于k-1位而言,如果没有数,答案不变,否则答案乘以2,最终贡献为
,有
但是原题卡k=64非常紧,所以不妨设数,避免讨论,
反思:1.求较大次方尽量用128
2.unsigned long long限制在2^64-1
3.如果define,那么在循环内的数不应放在int中,如for(int i=1,x;i<=n;i++),显然这里的x要unsigned
4.128局部求解,心态
5.较简单的题在赛场上可重码一遍,一定用清晰的马蜂
6.数据类型, noip rp++
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int N = 1e6 + 10;
int n,m,c,k,ans;
int a[N],b[N],d[N];
bool v[N];
void print(__int128 p){
if(p>9) print(p/10);
putchar(p%10+'0');
}
signed main(){
// cout<<(100>>10);
cin>>n>>m>>c>>k;
for(int i=1,x;i<=n;i++){
cin>>x;
for(int j=k-1;j>=0;j--)
a[j]|=(x>>j)&1;
}
// for(int i=0;i<=30;i++) cout<<a[i];
for(int i=1,x,y;i<=m;i++){
cin>>x>>y;
if(!a[x]){
v[x]=true;
//x位一定不为1
}
}
int sum=0;
for(int i=0;i<k;i++){
if(!v[i]) sum++;
}
if(sum<64){
__int128 ans=pow(2,sum);ans-=n;
print(ans);
}
else{
if(n==0) cout<<"18446744073709551616";
else{
__int128 p=pow(2,64);p-=n;
print(p);
}
}
return 0;
}
//100 110
再分享一下s2的屎山代码:copy
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
string cal(int a[]){
string ans="";
for(int i=1;i<=5;i++) ans+=char(a[i]+48);
return ans;
}
int read(){
int x=0,f=1;
char ch=getchar();
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;
}
int n,a[N],ans=1e9,b[N];
map<string,int> t,g;
vector<string> v[20];
int main(){
// freopen("lock.in","r",stdin);
// freopen("lock.out","w",stdout);
n=read();
for(int q=1;q<=n;q++){
t.clear();
ans=0;
for(int i=1;i<=5;i++){
a[i]=read();
b[i]=a[i];
}
if(n==1){
for(int i=1;i<=5;i++)
for(int j=0;j<=9;j++){
if(b[i]==j) continue;
int last=b[i];
b[i]=j;
if(!t[cal(b)]){
t[cal(b)]=true;
ans++;
}
}
for(int i=2;i<=5;i++)
for(int j=0;j<=9;j++){
int last1=a[i-1],last2=a[i];
a[i-1]=(a[i-1]+j)%10;a[i]=(a[i]+j)%10;
if(!t[cal(a)]){
t[cal(a)]=true;
ans++;
}
a[i-1]=last1;a[i]=last2;
}
cout<<ans;
return 0;
}
for(int i=1;i<=5;i++)
for(int j=0;j<=9;j++){
if(b[i]==j) continue;
int last=b[i];
b[i]=j;
if(!t[cal(b)]){
t[cal(b)]=true;
v[q].push_back(cal(b));
ans++;
a[i]=last;
}
}
for(int i=2;i<=5;i++)
for(int j=0;j<=9;j++){
int last1=a[i-1],last2=a[i];
a[i-1]=(a[i-1]+j)%10;a[i]=(a[i]+j)%10;
if(!t[cal(a)]){
t[cal(a)]=true;
v[q].push_back(cal(a));
ans++;
}
a[i-1]=last1;a[i]=last2;
}
}
for(int i=1;i<=n;i++)
for(string j:v[i]){
g[j]++;
}
for(int i=1;i<=n;i++){
int sum=0;
for(string j:v[i]){
if(g[j]==n) sum++;
}
ans=min(ans,sum);
}
cout<<ans;
return 0;
}