2020 CCPC-Wannafly Winter Camp
Day1 (Div.1&2)——A
7-1 1A. 期望逆序对
题解:
主要考虑以上两种情况
贪心排序时按照 a.l+a.r<b.l+b.r 来排序,由于逆序对要求最小,所以当满足图上标号为b的长度小于a的长度时可以满足逆序对最小,可以推出上式子。
计算期望时,依据上图可推出式子,注意公共部分取二分之一。
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
const int N=1e5+50;
int inv[N];
struct node {
int l,r;
} zz[N];
bool cmp(node a,node b) {
return a.l+a.r<b.l+b.r;
}
int quick_mod(int a,int b) {
int ans=1%mod;
while(b) {
if(b&1)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return ans;
}
int cal(node k1,node k2) {
int l=max(k1.l,k2.l);
if (l>k1.r) return 0;
int r=min(k1.r,k2.r);
int ans=1ll*(l-k2.l+r-k2.l)*(r-l+1)/2%mod;
ans=(ans+1ll*(k1.r-r)*(k2.r-k2.l+1))%mod;
return ans;
}
int main() {
int n;
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
scanf("%d %d",&zz[i].l,&zz[i].r);
}
sort(zz+1,zz+n+1,cmp);
for(int i=1; i<=n; ++i)
inv[i]=quick_mod((zz[i].r-zz[i].l+1),mod-2);
//for(int i=1;i<=n;++i)printf("%d\n",inv[i]);
int ans=0;
for(int i=1; i<=n; ++i) {
for(int j=i+1; j<=n; ++j) {
ans=(ans+(1ll*inv[i]*inv[j])%mod*cal(zz[i],zz[j]))%mod;
}
}
printf("%d\n",ans%mod);
return 0;
}
Day2 (Div.1&2)——C
纳新一百和乱得尬得在玩取石子的游戏。他们一共有N堆石子,第i堆有a
i
颗石子(若a
i
=0则表示这是一堆空石子堆)。
纳新一百和乱得尬得轮流进行游戏,纳新一百先手。轮到某个人时,他需要选择一堆非空的石子堆,并拿走任意数量的石子。如果不存在一堆非空的石子堆,则轮到的人输掉游戏。纳新一百想要知道,他的第一轮操作有多少种不同的取法能够保证他最后取得游戏的胜利。假设两个人都是用最优策略在玩游戏,两种操作方式视为不同当且仅当两种方式选取的石子堆的序号不同或取走的石子数量不同。
为了增加趣味性,纳新一百和乱得尬得决定对前i堆石子都玩一次游戏,两次游戏相互独立,也就是说,每开始一个新的游戏,石子堆都会被复原。
现在,纳新一百想要知道每一次游戏中,他能够取得胜利的第一轮操作方案数。
输入格式:
第一行一个正整数N(1⩽N⩽10
5
),表示石子堆数。 第二行N个数,表示a
i
(0⩽a
i
<2
60
)。
输出格式
N行,每行一个整数。第i行的整数表示用前i堆石子玩游戏时,纳新一百在第一轮有多少种操作方式保证自己能获得胜利。如果纳新一百无论如何都不可能赢得游戏,输出0。
输入样例:
6
0 0 2 8 7 0
输出样例:
0
0
1
1
1
1
尼姆博奕—Nim Game
异或和为零则先手必败,所以只要第一次取完之后满足异或和为零即可,取完后异或和为零,只需要将一堆石子的数量y变为x xor y(x为异或和)(异或两次同一个数,异或结果不变),所以只要y大于x xor y即可,考虑异或和的最高的为1的二进制位,所有这一位是1的y显然都满足条件,这一位是0的都不满足条件。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
ll a[N];
int sum[100];
void solve(ll x) {
int cut=0;
while(x) {
if(x%2)sum[cut]++;
x/=2;
cut++;
}
return;
}
int solve2(ll x) {
int cut=0;
while(x) {
cut++;
x/=2;
}
return cut-1;
}
int main() {
int n;
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
scanf("%lld",&a[i]);
}
ll ans=0;
for(int i=1; i<=n; ++i) {
ans^=a[i];
solve(a[i]);
printf("%d\n",sum[solve2(ans)]);
}
return 0;
}
推荐阅读
-
2020 CCPC Wannafly Winter Camp Day1 A,B,E~I题解
-
2020 CCPC Wannafly Winter Camp Day1 F 乘法 (二分)
-
2020 CCPC Wannafly Winter Camp Day2 Div.1&2(A 托米的字符串)
-
2020 CCPC Wannafly Winter Camp Day1H
-
2020 CCPC Wannafly Winter Camp Day1 H 最大公约数(唯一分解定理)
-
2020 CCPC Wannafly Winter Camp Day1 F 乘法(二分)
-
CCPC-Wannafly Winter Camp Day2 H
-
2020 CCPC Wannafly Winter Camp Day1 B 密码学( 模拟)
-
2020 CCPC Wannafly Winter Camp Day1 Div.1&2(A题 期望逆序对)(找规律)
-
2020 CCPC-Wannafly Winter Camp