codeforces 400E. Inna and Binary Logic 线段树
给出n个数, 定义a[1][i]为这初始的n个数, 然后a[i][j] = a[i-1][j]&a[i-1][j-1], 这样就可以得到一个三角形一共n*(n-1)/2个数。
给出一种操作, 将a[1][x]这个位置的数换为y, 然后求换完之后的这n(n-1)/2个数的和。
很有意思的题, 这个题应该按位建线段树, 这样需要建18棵, 因为a[1][i]的最大值为1e5。
然后我们来看具体如何做, 我们来看一组数据:3 6 7, 换为二进制之后是下面这个样子。
0 1 1
1 1 0
1 1 1
我们先来算一算这三个数的值为多少, 3+6+7+2+6+2 = 26。
我们发现第一个数和第二个数&之后剩余的是2, 第二个数和第三个数&之后剩余的是6, 我们来观察二进制, 发现第一个数和第二个数的第二位的2个1是相邻的, 并且这一位换成10进制正好是2, 而第二个数和第三个数的第一位和第二位的两个1是相邻的, 换成10进制之后是6。
由此可以推断出, 如果是一个单独的1, 那么贡献就是1, 两个相邻的1贡献是2*3/2 = 3,n个相邻的1贡献就是n(n+1)/2。
那么我们建立线段树的时候就应该保存一个sum, prefix, 以及suffix, 具体的看代码。
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 1e5+;
ll cal(ll val) {
return 1LL*val*(val+)/;
}
struct SegmentTree
{
ll sum[maxn<<], pre[maxn<<], suf[maxn<<];
void pushUp(int rt, int m) {
sum[rt] = sum[rt<<|] + sum[rt<<];
if(pre[rt<<|]&&suf[rt<<]) {
sum[rt] += cal(pre[rt<<|]+suf[rt<<])-cal(suf[rt<<])-cal(pre[rt<<|]);
}
pre[rt] = pre[rt<<];
suf[rt] = suf[rt<<|];
if(pre[rt] == m-(m>>)) {
pre[rt] += pre[rt<<|];
}
if(suf[rt] == m>>) {
suf[rt] += suf[rt<<];
}
}
void update(int p, int val, int l, int r, int rt) {
if(l == r) {
sum[rt] = pre[rt] = suf[rt] = val;
return ;
}
int m = l+r>>;
if(p<=m)
update(p, val, lson);
else
update(p, val, rson);
pushUp(rt, r-l+);
}
}tree[];
int main()
{
int cnt, n, m, x, y, a[];
cin>>n>>m;
for(int i = ; i<=n; i++) {
scanf("%d", &x);
cnt = ;
while(x) {
a[cnt++] = x&;
x>>=;
}
for(int j = ; j<cnt; j++) {
tree[j].update(i, a[j], , n, );
}
}
while(m--) {
scanf("%d%d", &x, &y);
cnt = ;
mem(a);
while(y) {
a[cnt++] = y&;
y>>=;
}
ll ans = , mul = ;
for(int i = ; i<; i++) {
tree[i].update(x, a[i], , n, );
ans += tree[i].sum[]*mul;
mul*=;
}
cout<<ans<<endl;
}
return ;
}
codeforces 400E. Inna and Binary Logic 线段树的更多相关文章
- [Codeforces 266E]More Queries to Array...(线段树+二项式定理)
[Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...
- [Codeforces 280D]k-Maximum Subsequence Sum(线段树)
[Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...
- codeforces 1217E E. Sum Queries? (线段树
codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...
- Codeforces 444 C. DZY Loves Colors (线段树+剪枝)
题目链接:http://codeforces.com/contest/444/problem/C 给定一个长度为n的序列,初始时ai=i,vali=0(1≤i≤n).有两种操作: 将区间[L,R]的值 ...
- Codeforces Gym 100513F F. Ilya Muromets 线段树
F. Ilya Muromets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/probl ...
- Codeforces 834D The Bakery【dp+线段树维护+lazy】
D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...
- codeforces 1017C - Cloud Computing 权值线段树 差分 贪心
https://codeforces.com/problemset/problem/1070/C 题意: 有很多活动,每个活动可以在天数为$[l,r]$时,提供$C$个价格为$P$的商品 现在从第一天 ...
- Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)
题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...
- Codeforces 446C DZY Loves Fibonacci Numbers [线段树,数论]
洛谷 Codeforces 思路 这题知道结论就是水题,不知道就是神仙题-- 斐波那契数有这样一个性质:\(f_{n+m}=f_{n+1}f_m+f_{n}f_{m-1}\). 至于怎么证明嘛-- 即 ...
随机推荐
- 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类
1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...
- Android 自动编译、打包生成apk文件 3 - 使用SDK Ant方式
相关文章列表: < Android 自动编译.打包生成apk文件 1 - 命令行方式> < Android 自动编译.打包生成apk文件 2 - 使用原生Ant方式> &l ...
- 如何给Ubuntu 安装Vmware Tools
http://jingyan.baidu.com/article/3065b3b6e8dedabecff8a435.html
- 关于K-Means算法
在数据挖掘中,K-Means算法是一种cluster analysis的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法. 问题 K-Means算法主要解决的问题如下图所示. ...
- 【转】在SQL Server 2008中SA密码丢失了怎么办?
sql server 2008的sa用户莫名其妙就登陆不进去了.提示如下: 以上提示就表明是密码错误,但密码我可是记得牢牢的,也许是系统被黑的原因吧.一直以来我的Windows身份验证就用不起,以下方 ...
- oracle基础代码使用
create or replace procedure pr_test1 is v_case ) :;--定义变量 begin -- /*判断语句 then dbms_output.put_line( ...
- Java基础之静态变量
public class StaticVariable { public static void main(String[] args) { Person p1 = new Person(); Per ...
- ;(function( $, window, undefined ){ }(jQuery,window))为何需要往里面传$,window,undefined这些参数
(function( $, jQuery , undefined ) {})(jQuery); 为什么要将window和undefined作为参数传给它? 因为 ecmascript 执行JS代码是从 ...
- TJU 2944 Mussy Paper 最大权闭合子图
传送门 给你一些东西, 每个东西有一个值,有正有负. 在给一些关系, 选了其中一个物品, 和他有关系的也必须全都选上, 关系是单向的. 问最后的最大价值是多少, 如果小于0输出“ **** ”( ...
- latex 批量注释
在LaTex中的注释有3种方法: 1. 右键单击选中要注释的文本,选择 Insert Comment ,WinEdt 就会自动给选定的行添加 % ,完成段落文本的注释: 右键单击选中已经注释的文本,选 ...