11.11
作者:互联网
这次考试有几个过失:
- 极限数据跑不过,优先卡常而不是思考优化算法
- 面对难题,看到只有暴力分就没有了梦想,没有想进一步优化暴力
A. 最大或
这道题八仙过海,这里讲一下我的思路。
#include<cstdio> #include<iostream> #include<cstring> #define ll long long using namespace std; ll l,r; int main(){ freopen("maxor.in","r",stdin); freopen("maxor.out","w",stdout); int T;scanf("%d",&T); while(T--){ scanf("%lld%lld",&l,&r); ll maxor=r; for(ll i=r;i>=l;i-=i&-i) if(i-1>=l) maxor=max(maxor,r|(i-1)); printf("%lld\n",maxor); } }
首先r一定选,所以我们考虑一下谁和r配对就可以使答案最大化。
发现把1变成0的操作是没有意义的对了吧,所以我们只需要考虑把0变成1的操作即可。
为什么把0变成1呢?
r有了一些“1”,这些1另一半并不需要强制有,我们可以考虑把它们换成更多的更小的“1”。
又怎么把0变成1呢?
每次跳r的lowbit,然后把r的最小的1去掉,再把当前的r-1和最初的r或。
为什么它会遍历最优解呢?
在这种情况下,所有无用的,使“1”减少的情况我们都会忽略,所有使1增加的情况我们都会具有。
所以它是对的。
B. 答题
部分分已经给了我们启发,要分一半来考虑。
把概率P乘上$2^n$就变成了我们要超过几种方案。
那么dfs前一半和后一半,然后二分答案mid,判断和$<=mid$的方案数。
这里由于我们枚举前一半递增那么后一半一定单调不升,我们可以用单调指针扫过去。
注意这里如果用upper——bound就会得到 连 暴 力 都 不 如 的30pts。
C. 联合权值·改
考虑分开讨论两个问题的答案。
最大值:
枚举u点我们把所有u连的点按找权值排序,再枚举w连的点,然后bitset判断v是否出三元环了,不是就直接取max,break。
考虑复杂度,边数为m的图最多有$m^{1.5}$的三元环数量,就是点数为$m^{0.5}$时的完全图。
只有在出三元环的时候我们才会继续枚举v和w,所以最多$m^{1.5}$次失败枚举我们就能找出从每个点出发的最大值。
权值和:
考虑枚举w中间点,w连着的点的权值和的平方就是答案+多余。有哪些冗余呢?
u和v相等的情况:可以轻松搞掉。
u和v连边的情况:把所有三元环都删掉就是了。
现在变成了如何求三元环的个数了,这里给出一种复杂度上限为$m^{1.5}$的解法。
把所有点按照度数降序排序,然后标上编号,合法的边是起点的编号小于终点的编号的边。
首先正确性是可以保证的,相当于把无向图奇怪的定向了。
考虑复杂度如何保证的。度数大于$\sqrt{m}$的点不会超过$\sqrt{m}$个,所以我们让他们随便连m条边也不会超过$m^{1.5}$。
度数小于$\sqrt{m}$的点,就算有m个这样的点也问题不大,复杂度不会超过$m^{1.5}$。
所以复杂度正确。
就这样我们三重循环枚举u,w,v然后判断$u$$v$之间是否有边就可以判断是否有三元环了。
可是$O(n^3)$的 裸 暴 力 9 5 p t s 是 什 么 鬼 啊 。
标签:1.5,maxor,复杂度,11.11,枚举,三元,ll 来源: https://www.cnblogs.com/hzoi2018-xuefeng/p/11845548.html