7-8 what‘s 莫比乌斯最大值(2023郑州轻工业大学校赛
Posted Demoo.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7-8 what‘s 莫比乌斯最大值(2023郑州轻工业大学校赛相关的知识,希望对你有一定的参考价值。
题意:
有n个问题和闲聊
问题的格式是’what’s + S 问题 S_问题 S问题’
闲聊的格式是 S 问题 S_问题 S问题+ S 回答 S_回答 S回答, S 问题 S_问题 S问题的长度>=0
对于每个 S 回答 S_回答 S回答 ,只能回答在这句话之前提问的问题
那么求最多能回答几个不同的问题
思路:
对于每个回答,他的每个前缀都可能是一个出现过的问题
那么我们对于一个回答,让他贪心的回答出现过的前缀最长的问题
因为对于一个回答,如果他的长度长,可以回答长度长的问题和长度短的问题,如果他的长度短的话就只能回答长度短的问题,所以我们优先让他回答没有回答过的长度最长的问题
用umap来记录一个问题是否出现过,以及是否被回答过。
注意:
加了ios::sync_with_stdio(false)就不能用getchar(),需要用cin.get()
对于map的每次询问都是插入,如果对于每出现过的map,需要先判断是否出现过载判断值,可以节省时间防止tle
#include<bits/stdc++.h>
using namespace std;
const int N=4e6+10;
int idx,n;
int main()
ios::sync_with_stdio(false);
cin.tie(),cout.tie();
cin>>n;
cin.get();//加了ios不能用getchar
unordered_map<string,int> chuxian;//记录是否被回答过,如果等于0就是没有
unordered_map<string,int> huida;
int con=0;
for(int i=1;i<=n;i++)
string s;
cin>>s;
if(s=="what's")
cin>>s;
chuxian[s]=1;
else
string op;
int id=-1;
string ans;
for(int i=0;i<s.size();i++)
op+=s[i];
if(chuxian.count(op)&&chuxian[op]==1&&huida.count(op)==0)
id=i;
ans=op;
if(id!=-1)
huida[ans]=1;
con++;
cout<<con;
return 0;
[HAOI2015] 按位或 - Min-Max容斥,快速莫比乌斯变换
初态下,分数为 (0)。每秒钟,随机选择一个 ([0,2^n-1]) 的数字与当前的数字做按位或运算。选择数字 (i) 的概率是 (p_i),求分数达到 (2^n-1) 的期望时间。(nleq 20)
Solution
先介绍一下 Min-Max 容斥原理。设 (max(S),min(S)) 分别是集合 (S) 中的最大值与最小值,则有
[
max(S)=sum_{Tsubseteq S} (-1)^{|T|+1} min(T)
\min(S)=sum_{Tsubseteq S} (-1)^{|T|+1} max(T)
]
Min-Max 容斥原理对随机变量的期望成立。
回到原问题,对于某个位置集合,考虑将每个位变为 (1) 的时间扔进一个集合,那么 (min(S)) 是集合中第一个变 (1) 元素的时间,(max(S)) 是最后一个。
于是答案就是 (E(max(U))),其中 (U) 为全集。利用 Min-Max 容斥原理我们可以将它转化为求对于每一个子集的 (E(min(S))),而 (min(S)) 符合几何分布,于是有
[
egin{aligned}
E(min(S)) &= sum_{i=1}^{infty} iP(min(S)=i)
&= sum_{i=1}^infty i(sum_{TS=varnothing}p_T)^{i-1}(1-sum_{TS=varnothing}p_T)
&= frac{1}{1-sum_{TS=varnothing}p_T}
end{aligned}
]
于是现在我们需要对所有 (Ssubseteq U),求出 (sum_{TS=varnothing} p_T)
考虑 FMT,可以用来求出 (forall S, g(S)=sum_{Tsubseteq S} f(T))
#include <bits/stdc++.h>
using namespace std;
double a[2000005],ans;
int n;
signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=0;i<1<<n;i++) cin>>a[i];
int up=1<<n;
for(int k=1;k<up;k<<=1)
for(int s=0;s<up;s+=k<<1)
for(int i=s;i<s+k;i++)
{double a0=a[i];double a1=a[i+k];a[i]=a0;a[i+k]=a0+a1;}
for(int i=1;i<up;i++) {
if(1-a[(up-1)^i]<1e-10) {
puts("INF");
return 0;
}
ans += (__builtin_popcount(i)%2?1:-1)*1/(1-a[(up-1)^i]);
}
printf("%.8lf",ans);
}
以上是关于7-8 what‘s 莫比乌斯最大值(2023郑州轻工业大学校赛的主要内容,如果未能解决你的问题,请参考以下文章