AIsing Programming Contest 2020
A - Number of Multiples
B - An Odd Problem
C - XYZ Triplets
前三题差点让我以为走错片场,正片开始
D - Anything Goes to Zero
题解
设二进制1的个数为cnt
然后分别预处理原数在模cnt+1和模cnt-1的情况下的答案,以及\(2^i\) 在这两个模意义下的答案,然后就方便统计了
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,a[200010],cnt,ans1,ans2,f1[200010],f2[200010];
char str[200010];
int f(int x)
{
if(x==0)return 0;
int tmp=x,count=0;
while(tmp)
{
if(tmp&1)count++;
tmp>>=1;
}
return 1+f(x%count);
}
int main()
{
n=read();
scanf("%s",str);
for(int i=0;i<n;i++)a[i]=str[i]-'0',cnt+=(a[i]==1);
if(cnt!=1)
{
for(int i=0;i<n;i++)ans1=(ans1*2+a[i])%(cnt-1);
}
for(int i=0;i<n;i++)ans2=(ans2*2+a[i])%(cnt+1);
f1[n-1]=1;f2[n-1]=1;
if(cnt!=1)
{
for(int i=n-2;i>=0;i--)f1[i]=(f1[i+1]*2)%(cnt-1);
}
for(int i=n-2;i>=0;i--)f2[i]=(f2[i+1]*2)%(cnt+1);
for(int i=0;i<n;i++)
{
int temp;
if(a[i]==1)
{
if(cnt==1){printf("0\n");continue;}
temp=(ans1+cnt-1-f1[i])%(cnt-1);
}
else temp=(ans2+f2[i])%(cnt+1);
printf("%d\n",1+f(temp));
}
return 0;
}
/*
1110111001011011001110
*/
事后补题
E - Camel Train
题解
题目大意:有\(n\) 个物品,要对这\(n\) 个物品进行一个排列,对于第\(i\) 个物品,如果他排在\(k_i\) 及之前,会得到\(a_i\) 的收益,否则会得到\(b_i\) 的收益,现在令收益最大。
F - Two Snuke
题解
还不太会插值。
废话
为什么不能用#include<bits/stdc++.h>呜呜呜呜