BZOJ5312
其实这道题写个假算法是完全可以过的 自己先写了一发假算法也是过的很快乐 就是让区间maxx = 区间minn的时候 你直接进行区间修改即可
这是假算法代码

/*if you can't see the repayWhy not just work step by steprubbish is relaxedto ljq
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define lc (rt<<1)
#define rc (rt<<11)
#define mid ((l+r)>>1)typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);
const int MAX_N = 200025;
int maxx[MAX_N<<2],col[MAX_N<<2],minn[MAX_N<<2];
void up(int rt)
{maxx[rt] = max(maxx[rt<<1],maxx[rt<<1|1]);minn[rt] = min(minn[rt<<1],minn[rt<<1|1]);
}
void build(int rt,int l,int r)
{col[rt] = -1;if(l==r){int v;scanf("%d",&v);maxx[rt] = minn[rt] = v;return ;}build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);up(rt);
}
void down(int rt,int l,int r)
{if(col[rt]!=-1){col[rt<<1] = col[rt<<1|1] = col[rt];maxx[rt<<1] = maxx[rt<<1|1] = col[rt];minn[rt<<1] = minn[rt<<1|1] = col[rt];col[rt] = -1;}
}
void And(int rt,int l,int r,int x,int y,int v)
{if(x<=l&&r<=y&&maxx[rt]==minn[rt]){maxx[rt] = maxx[rt]&v;minn[rt] = minn[rt]&v;col[rt] = maxx[rt];return ;}down(rt,l,r);if(x<=mid) And(rt<<1,l,mid,x,y,v);if(mid<y) And(rt<<1|1,mid+1,r,x,y,v);up(rt);
}
void Or(int rt,int l,int r,int x,int y,int v)
{if(x<=l&&r<=y&&maxx[rt]==minn[rt]){maxx[rt] = maxx[rt]|v;minn[rt] = minn[rt]|v;col[rt] = maxx[rt];return ;}down(rt,l,r);if(x<=mid) Or(rt<<1,l,mid,x,y,v);if(mid<y) Or(rt<<1|1,mid+1,r,x,y,v);up(rt);
}
int query(int rt,int l,int r,int x,int y)
{if(x<=l&&r<=y){return maxx[rt];}down(rt,l,r);int maxx1 = 0,maxx2 = 0;if(x<=mid) maxx1 = query(rt<<1,l,mid,x,y);if(mid<y) maxx2 = query(rt<<1|1,mid+1,r,x,y);return max(maxx1,maxx2);
}
int main()
{//ios::sync_with_stdio(false);//freopen("a.txt","r",stdin);//freopen("b.txt","w",stdout);int n,Q,opt,x,y,v;scanf("%d%d",&n,&Q);build(1,1,n);while(Q--){scanf("%d",&opt);if(opt==1){scanf("%d%d%d",&x,&y,&v);And(1,1,n,x,y,v);}else if(opt==2){scanf("%d%d%d",&x,&y,&v);Or(1,1,n,x,y,v);}else{scanf("%d%d",&x,&y);printf("%d\n",query(1,1,n,x,y));}}//fclose(stdin);//fclose(stdout);//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;return 0;
}

学了一下正解的意思 因为你按位与 与 按位或 都是对一段区间相当于赋值了 那么你修改的次数越多 区间内相同的个数(指 0 1是单调不减的
那么我们重新定义一个same数组 same数组代表什么呢? 代表 1 - 20 位区间内每个数在该位是否相同 比如如果每区间内每个数 都含有 1<<i 这个数 那么他们在iii位上就是1
所以在一开始的build函数里面我们要让所有的叶子same[rt] 为(1<<20)-1
然后注意up的时候same怎么更新
我们知道same一定是由左儿子的same & 上右儿子的same 但是有可能左儿子same 为 1那位都是0 右儿子same 为1 那位都是1 所以我们还要排除这种影响 也就是 &(~(maxx[rt<<1]^maxx[rt<<1|1]))
down操作同理 就是从爸爸传递下去的时候 如果第i位same为0并且maxx[rt]在此位为1 说明这个区间肯定有这个1<<i 这个数
所以我们只要 maxx[rt]&(~sm) 代表上面意思
然后mx&sm就是爸爸中一定相等的 两者取 & 即可
至于And 与 Or 则是用一个小trick 使得 And变成 Or 值得记住
可以手推一下
比假算法慢 (滑稽)
这里与变或的小trick 就是或 要v&inv | 不在v里面的1位置
而 And 与 Or 之间有~的关系 所以要 v^inv | 不在v里面的1位置 但是因为是与 所以不|(v&inv)

/*if you can't see the repayWhy not just work step by steprubbish is relaxedto ljq
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
#define lc (rt<<1)
#define rc (rt<<11)
#define mid ((l+r)>>1)typedef pair<int,int> pll;
typedef long long ll;
const int inf = (1<<20)-1;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
void exgcd(ll a,ll b,ll &x,ll &y,ll &d){if(!b) {d = a;x = 1;y=0;}else{exgcd(b,a%b,y,x,d);y-=x*(a/b);}}//printf("%lld*a + %lld*b = %lld\n", x, y, d);
const int MAX_N = 200025;
int maxx[MAX_N<<2],same[MAX_N<<2];
void up(int rt)
{maxx[rt] = max(maxx[rt<<1],maxx[rt<<1|1]);same[rt] = (~(maxx[rt<<1]^maxx[rt<<1|1]))&(same[rt<<1]&same[rt<<1|1]);
}
void build(int rt,int l,int r)
{if(l==r){int v;scanf("%d",&v);same[rt] = inf;maxx[rt] = v;return ;}build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);up(rt);
}
void pushnow(int rt,int sm,int mx)
{same[rt] |= sm;maxx[rt] = (mx&sm)|(maxx[rt]&(~sm));
}
void down(int rt)
{pushnow(rt<<1,same[rt],maxx[rt]);pushnow(rt<<1|1,same[rt],maxx[rt]);
}
void update(int rt,int l,int r,int x,int y,int sm,int v)
{if(y<l||x>r) return;if(x<=l&&r<=y){if(l==r||(sm&same[rt])==sm){maxx[rt] = (maxx[rt]&(~sm))|(v&sm);return ;}}down(rt);update(rt<<1,l,mid,x,y,sm,v);update(rt<<1|1,mid+1,r,x,y,sm,v);up(rt);
}
int query(int rt,int l,int r,int x,int y)
{if(y<l||x>r) return 0;if(x<=l&&r<=y){return maxx[rt];}down(rt);int maxx1 = 0,maxx2 = 0;maxx1 = query(rt<<1,l,mid,x,y);maxx2 = query(rt<<1|1,mid+1,r,x,y);return max(maxx1,maxx2);
}
int main()
{//ios::sync_with_stdio(false);//freopen("a.txt","r",stdin);//freopen("b.txt","w",stdout);int n,Q,opt,x,y,v;scanf("%d%d",&n,&Q);build(1,1,n);while(Q--){scanf("%d",&opt);if(opt==1){scanf("%d%d%d",&x,&y,&v);update(1,1,n,x,y,inf^v,0);}else if(opt==2){scanf("%d%d%d",&x,&y,&v);update(1,1,n,x,y,v,v);}else{scanf("%d%d",&x,&y);printf("%d\n",query(1,1,n,x,y));}}//fclose(stdin);//fclose(stdout);//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;return 0;
}

【BZOJ 5312】 线段树 与 或 区间 max相关推荐

  1. 线段树2 求区间最小值

    线段树2 求区间最小值 递归,DFS,尤其是二叉树,我只要知道我的返回节点就好,因为DFS的顺序一定是一样的,不同的题目和数据范围也是一样的,只是返回节点让DFS的深度不同. 递归的内容只有两部分:1 ...

  2. HDU 1166 敌兵布阵(线段树:点更新,区间求和)

    HDU 1166 敌兵布阵(线段树:点更新,区间求和) http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意: 给你n个整数,然后给你多条命令,每条命令如 ...

  3. hdu 1540(线段树单点更新 区间合并)

    解题思路:这一题要求的是连续区间,所以可以把它的子区间合并,这里运用线段树,但是在保存节点信息的方面要做一点修改 lsum:从这个区间的左端点往右能够找到的最大连续区间: rsum:从这个区间的右端点 ...

  4. 2021牛客多校4 - Tree Xor(线段树+异或区间拆分)

    题目链接:点击查看 题目大意:给出一棵 nnn 个点组成的树,每个点权的取值范围是 [li,ri][l_i,r_i][li​,ri​],每条边权代表的是两点的异或值,现在问这棵树有多少种有效赋值 题目 ...

  5. 线段树维护(最大区间和,最大子段和,最长连续上升子序列)

    本文主要介绍用线段树来维护(最大区间和,最大子段和,最长连续上升子序列)的问题. HDU 1540 Tunnel Warfare(最长连续区间+单点修改) 洛谷 P2894 [USACO08FEB]酒 ...

  6. 2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询...

    D - 秋实大哥与战争 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 D ...

  7. WUST 1255 巧克力(线段树的单点区间更新查询)

    1355: 巧克力 Time Limit: 1 Sec   Memory Limit: 128 MB   64bit IO Format: %lld Submitted: 190   Accepted ...

  8. 线段树应用:区间合并

    传送门luoguP2894 本题我们要维护最左边的值,考虑使用线段树维护.我们发现只用一个来存储当前的节点的值并不够,因为对于一个节点我们无法用一个来描述这整个区间哪些为空,哪些满了,例如查询的跨越了 ...

  9. BZOJ 4422 (线段树、DP、扫描线、差分)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4422 我真服了..这题我能调一天半,最后还是对拍拍出来的...脑子还是有病啊 题解: ...

最新文章

  1. 比特币和加密货币入门
  2. thinkphp pathinfo nginx 无法加载模块:Index
  3. IE11 统治浏览器市场 Chrome 终超 Firefox
  4. SED单行脚本快速参考(Unix流编辑器)
  5. Windows环境下MySQL 8.0 的安装、配置与卸载
  6. AQS抽象队列同步器详解(待更新)
  7. 通过栈(Stack)实现对树的遍历
  8. [C++11]共享智能指针shared_ptr指定删除器
  9. python 类和对象 经常用吗_python基础教程之对象和类的实际运用
  10. 解决Docker容器时间与主机不一致问题
  11. 当post 的字段很多,post的字段并不完全修改(有的值是前端input的值,有的任保留原来原来数据库的值),...
  12. java多态 -- 猫狗案列
  13. GTK+的编译还真麻烦
  14. 红帽操作系统 RHEL 8.1 官方ISO镜像下载
  15. 腾讯云服务器手动建立WordPress个人站点Windows系统教程-Unirech腾讯云国际版代充
  16. 基础破解XP/Win 7开机密码方法(粘滞键漏洞)
  17. 01 Spark组件 —— Scala导言
  18. bootstrap学习使用
  19. 谈谈英语学习(5):听力
  20. Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255]

热门文章

  1. Group_concat()函数使用介绍
  2. python之正弦图
  3. PhotoShop算法实现高级篇--色彩特效(三十五)
  4. LAPS本地管理员密码之使用PowerShell查看和重置密码
  5. 单片机数码管6位时钟c语言,单片机6位数码管时钟
  6. 网络攻防之dns劫持与网页挂马(实测)
  7. cad和mysql_什么是cad
  8. The supplied data appears to be in the Office 2007+ XML
  9. mongrel cluster
  10. 单向直播面临升级,网易视频云首推多路互动直播