首页 > 其他分享 >Luogu P2114 起床困难综合症

Luogu P2114 起床困难综合症

时间:2024-09-07 09:13:33浏览次数:13  
标签:tmp break int Luogu P2114 long 综合症 case op

Luogu P2114 起床困难综合症

由于这道题的三个操作都是位运算,所以我们可以按位考虑,即考虑初始攻击力和最后伤害的每一位分别是 $0$ 还是 $1$。

因此我们可以先算出每一位分别取 $0$ 和取 $1$ 在经过所有防御门后最后得到的是什么,然后从高位向低位贪心即可。

需要注意的是(也是被卡了很久 $60$ 分的原因),最后得到的攻击力可能远大于 $m$,其上限应当为 $2 ^ {31} - 1$(因为 $10 ^ {9}$ 对应的二进制有 $30$ 位),因此我们循环的范围不应由 $m$ 的二进制位数确定。

#include <bits/stdc++.h>
#define N 100010

int n, m;
int op[N], t[N], f[32][2];
long long ans;

namespace WalkerV {
    void Read() {
        scanf("%d %d", &n, &m);
        for (int i = 0; i < n; i++) {
            char tmp[5];
            getchar();
            scanf ("%s %d", tmp, &t[i]);
            switch (tmp[0]) { //or - 1, xor - 2, and - 3
                case 'O':
                    op[i] = 1;
                    break;
                case 'X':
                    op[i] = 2;
                    break;
                case 'A':
                    op[i] = 3;
                    break;
            }
        }
        return;
    }

    void Solve() {
        for (int k = 0; k <= 30; k++) {
            int val = 0;
            for (int i = 0; i <= 1; i++) {
                int tmp = i;
                for (int j = 0; j < n; j++) {
                    switch (op[j]) {
                        case 1:
                            tmp |= ((t[j] >> k) & 1);
                            break;
                        case 2:
                            tmp ^= ((t[j] >> k) & 1);
                            break;
                        case 3:
                            tmp &= ((t[j] >> k) & 1);
                            break;
                    }
                }
                f[k][i] = tmp;
            }
        }
        long long tmp = 0;
        for (int i = 30; i >= 0; i--) {
            if ((f[i][0] < f[i][1]) && (tmp + (1 << i) <= m)) {
                tmp += (1 << i), ans += (f[i][1] << i);
            }
            else {
                tmp += (0 << i), ans += (f[i][0] << i);
            }
        }
        return;
    }

    void Print() {
        printf("%lld\n", ans);
        return;
    }
}

int main()
{
    WalkerV::Read();
    WalkerV::Solve();
    WalkerV::Print();
    return 0;
}

标签:tmp,break,int,Luogu,P2114,long,综合症,case,op
From: https://www.cnblogs.com/luoshui-tianyi/p/18401327

相关文章

  • Luogu8990 做题记录
    link比较喜欢的题目。考虑合法的条件,从点亮的灯的角度难以维护。反过来看,从未点亮的灯角度考虑,条件相当于这些灯形成了一个包含\(1\)号灯的连通块。如何判定这些灯形成一个连通块?点减边!设\(c_i\)为操作前\(i\)次后,未点亮的灯的\(|V|-|E|\)的值,那么\(c_i=1\)即合......
  • luogu P3808/3796
    首先Trie树:#include<bits/stdc++.h>usingnamespacestd;intT,q,n,t[3000005][65],cnt[3000005],idx;chars[3000005];intgetnum(charx){if(x>='A'&&x<='Z')returnx-'A';elseif(x>='a......
  • [luoguP4051/JSOI2007] 字符加密
    题意给定字符串\(s\),输出将\(s\)的所有循环同构的字符串排序后,每个字符串的末尾的字符。sol因为要对循环同构的字符串排序,因此我们可以将\(s\)复制一遍,拼在后面,计算\(sa\),满足\(sa_i\len\)的所有元素的相对位置即为排序后字符串的相对位置,输出即可\(sa\)的计算详见......
  • [luoguP3809]后缀排序
    题意给定一个字符串,要求将它的所有后缀按照字典序排序,并按顺序输出每个后缀第一个字符的下标。sol这是后缀数组(SuffixArray,SA)的板子题。我们定义:\(s_{i\cdotsj}\)表示\(s\)中下标在\(i\)到\(j\)之间的子串。\(sa_i\)表示排名为\(i\)的后缀第一个字符的下标;\(......
  • Luogu P10997 Partition 题解 [ 蓝 ] [ 轮廓 dp ]
    Partition:一道dp神题,用到了以轮廓线的轨迹来做dp的技巧,和敲砖块这题的状态设计有点相似。观察首先观察样例,发现整张图可以看作是被两条线分隔开的。同时每个颜色的四个方向上又存在一大堆奇怪的性质,很容易发现这两条线一条是从左上到右下的线,另一条是从右下到左上的线。暴......
  • luoguP5369 [PKUSC2018] 最大前缀和
    题目n<=20题解想了半天3位状态的折半,然后发现空间开不下(时间也不太行)所以放弃思考,直接枚举答案答案是a中的一个集合,设为S;记集合S的和为sum[S]考虑当S确定时,有多少种方案能使答案恰好为sum[S]。为了处理多种sum相同的情况,记S为从前往后考虑,第一次出现最大ans的集合;记剩余部......
  • luoguP4907 A换B problem
    数据有点水,加个卡时就可以过。代码加注释送上:#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<ctime>#defineLLlonglongusingnamespacestd;LLread(){ LLk=0,f=1;charc=getchar(); while(c<......
  • Luogu P4425 转盘 题解 [ 黑 ] [ 线段树 ] [ 贪心 ] [ 递归 ]
    转盘:蒟蒻的第一道黑,这题是贪心和线段树递归合并的综合题。贪心破环成链的trick自然不用多说。首先观察题目,很容易发现一个性质:只走一圈的方案一定最优。这个很容易证,因为再绕一圈回来标记前面的和等前面的标记完之后继续走是等价的,并且再绕一圈甚至可能更劣。于是,我们只用走......
  • Luogu P4588 数学运算 题解 [ 绿 ] [ 线段树 ]
    LuoguP4588数学运算。虽然是一个很典的题,但里面的思想还是比较值得记录的。假做法一开始看到此题还以为是乘法逆元的模板题,但看到\(m\)与\(M\)不互质,就知道这种做法是假的了。注意exgcd虽然能求模数为合数的逆元,但是要是两数不互质就什么算法都搞不了了。因此,本题不能......
  • Luogu P7250 BalticOI 山峰 题解 [ 蓝 ] [ 模拟 ] [ 并查集 ] [ BFS ]
    LuoguP7250BalticOI山峰。一道大模拟,很暴力,也很难写。建议紫或蓝,标签为模拟、广度优先搜索、并查集。思路首先观察到答案取决于路线上的最低点,所以我们可以把所有点的高度丢进一个桶里,从大到小枚举,尝试更新答案。这应该是个挺经典的trick了。感性理解可以看作所有山都先......