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 是 什 么 鬼 啊 。

猜你喜欢

转载自www.cnblogs.com/hzoi2018-xuefeng/p/11845548.html