Codeforces 400E Inna and Binary Logic(位运算+暴力)

2024-06-05 03:58

本文主要是介绍Codeforces 400E Inna and Binary Logic(位运算+暴力),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:Codeforces 400E Inna and Binary Logic


题目大意:给出n和m,表示有n个数,m次修改,然后给出n个数的值a1[i],通过a1数组可以推断出a2数组,长的为a1的长度减一,接着a3、a4直到an(长度为1),ai[k] = ai-1[k] & ai-1[k+1].sun为所有数的和。每次修改有p和x两个值,表示将a1数组的第p个位置修改成x,输出修改后的sum。


解题思路:假设一开始计算好了sun,然后每一次修改的时候,x和t[p],只要考虑二进制的每个位即可,如果(x&(1<<i)) == (t[p]&(1<<i))那么不变;如果(x&(1<<i)) = 1, (t[p]&(1<<i))=0,那么就要加上s;否则减掉s;s的计算方法:从p往左,连续的l个数t[j]&(1<<i) = 1,往右连续r个数t[j]&(1<<i) = 1,s = (l + r + l*r) * (1<<i)。因为如果出现有一个t[j]&(1<<i) = 0,那么在它后面有多少个t&(1<<i) = 1也没有用。解决完修改的部分,初始值计算就是个问题了,一开始用o(n^2)的方法超时了,很费解。初始值计算,对于每个位i,遍历一遍数组,计算各个连续的片t&(1<<i) = 1的个数c,s += (c*(c+1)*(1<<i)).


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>using namespace std;
typedef long long ll;
const int N = 1e5+5;
int n, m, t[N];
ll s;void find(int k, ll& l, ll& r, int x) {l = r = 0;for (int i = x-1; i; i--) {if ((t[i]&k) == 0) break;l++;}for (int i = x+1; i <= n; i++) {if ((t[i]&k) == 0) break;r++;}
}void solve (int p, int x, int y) {ll l, r;for (int i = 0; (1<<i) < N; i++) {int k = (1<<i);if ((x&k) == (y&k)) continue;find(k, l, r, p);ll u = (l * r + l + r + 1) * (ll)k;if (x&k) {s += u;} else {s -= u;}}
}void init () {s = 0;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) scanf("%d", &t[i]);for (int i = 0; (1<<i) < N; i++) {int k = (1<<i);ll c = 0;for (int j = 1; j <= n; j++) {if (t[j]&k) c++;else {if (c) s += (c*(c+1)*(ll)k/2);c = 0;}}if (c) s += (c*(c+1)*(ll)k/2);}
}int main () {init ();int p, x;for (int i = 0; i < m; i++) {scanf("%d %d", &p, &x);solve (p, x, t[p]);t[p] = x;cout << s << endl;}return 0;
}


这篇关于Codeforces 400E Inna and Binary Logic(位运算+暴力)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1032010

相关文章

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

计蒜客 Half-consecutive Numbers 暴力打表找规律

The numbers 11, 33, 66, 1010, 1515, 2121, 2828, 3636, 4545 and t_i=\frac{1}{2}i(i+1)t​i​​=​2​​1​​i(i+1), are called half-consecutive. For given NN, find the smallest rr which is no smaller than NN

【Java中的位运算和逻辑运算详解及其区别】

Java中的位运算和逻辑运算详解及其区别 在 Java 编程中,位运算和逻辑运算是常见的两种操作类型。位运算用于操作整数的二进制位,而逻辑运算则是处理布尔值 (boolean) 的运算。本文将详细讲解这两种运算及其主要区别,并给出相应示例。 应用场景了解 位运算和逻辑运算的设计初衷源自计算机底层硬件和逻辑运算的需求,它们分别针对不同的处理对象和场景。以下是它们设计的初始目的简介:

位运算:带带孩子吧,孩子很强的!

快速进制 在聊到位运算之前,不妨先简单过一遍二进制的东西。熟悉二进制和十进制的快速转换确实是掌握位运算的基础,因为位运算直接在二进制位上进行操作。如果不熟悉二进制表示,很难直观理解位运算的效果。 这里主要涉及二进制和十进制之间的互相转换。 十进制转二进制 十进制转二进制可以使用常见的 除2取余法 进行。每次将十进制除以2并记录所得余数,直到商为0,然后再将记录的余数 从下往上排列即