BJ 集训测试10 序列
2018-03-26 18:43
344 查看
http://www.elijahqi.win/archives/2790
给定一个序列要求支持以下操作 区间取Min 区间加 还有询问区间是否单调递降
使用jry线段树 2016年国家集训队论文有讲
那么我需要在每个节点维护 最大值 次大值 和最小值 每次回答询问的时候只需要看下这个区间是否满足单调或者看一下我前面的最小值是否比我当前的最大值要小 这题细节较多
维护的时候如果mx2==-1的时候我需要将区间单调的标记修改
针对区间取min这个操作我需要首先pushdown 避免修改我的时候会影响到我这层的懒标记
修改的时候如果我比这一层最小的要小那么我直接给打上修改标记即可 如果比次大的大比最大的小我只需要把最大的改过来即可 同时打上标记 如果都不属于以上的几种情况 那么我们递归下去即可 据说复杂度是log^2的 但是常数很小
给定一个序列要求支持以下操作 区间取Min 区间加 还有询问区间是否单调递降
使用jry线段树 2016年国家集训队论文有讲
那么我需要在每个节点维护 最大值 次大值 和最小值 每次回答询问的时候只需要看下这个区间是否满足单调或者看一下我前面的最小值是否比我当前的最大值要小 这题细节较多
维护的时候如果mx2==-1的时候我需要将区间单调的标记修改
针对区间取min这个操作我需要首先pushdown 避免修改我的时候会影响到我这层的懒标记
修改的时候如果我比这一层最小的要小那么我直接给打上修改标记即可 如果比次大的大比最大的小我只需要把最大的改过来即可 同时打上标记 如果都不属于以上的几种情况 那么我们递归下去即可 据说复杂度是log^2的 但是常数很小
#include<cstdio> #include<algorithm> #define N 110000 #define lc x<<1 #define rc x<<1|1 #define inf 0x7f7f7f7f using namespace std; inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++; } inline int read(){ int x=0,f=1;char ch=gc(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=gc();} while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc(); return x*f; } struct node{ int mx,mx2,mn,flag,add,tag; }tree[N<<2];//flag=1 describe nonincrease int n,m,min1; inline void update(int x){ tree[x].mx=max(tree[lc].mx,tree[rc].mx); if (tree[lc].mx>tree[rc].mx&&tree[lc].mx!=tree[rc].mx){ if (tree[lc].mx2>tree[rc].mx) tree[x].mx2=tree[lc].mx2;else tree[x].mx2=tree[rc].mx; }else if (tree[rc].mx2>tree[lc].mx&&tree[lc].mx!=tree[rc].mx) tree[x].mx2=tree[rc].mx2;else tree[x].mx2=tree[lc].mx; if (tree[lc].mx==tree[rc].mx) tree[x].mx2=max(tree[lc].mx2,tree[rc].mx2); tree[x].mn=min(tree[lc].mn,tree[rc].mn);if(tree[x].mx2==-1) {tree[x].flag=1;return;} tree[x].flag=tree[lc].flag&&tree[rc].flag&&tree[lc].mn>=tree[rc].mx; } inline void build(int x,int l,int r){ if (l==r) {tree[x].mn=tree[x].mx=read();tree[x].mx2=-1;tree[x].flag=1;return;}int mid=l+r>>1; build(lc,l,mid);build(rc,mid+1,r);update(x); } inline void doadd(int x,int w){ tree[x].mx+=w;tree[x].mn+=w;tree[x].add+=w;if (tree[x].tag) tree[x].tag+=w;if (tree[x].mx2!=-1) tree[x].mx2+=w; } inline void dochange(int x,int w){ tree[x].mx=tree[x].mn=w;tree[x].mx2=-1;tree[x].tag=w;tree[x].flag=1; } inline void pushdown(int x){ if (tree[x].add) doadd(lc,tree[x].add),doadd(rc,tree[x].add),tree[x].add=0; if (tree[x].tag){int w=tree[x].tag;tree[x].tag=0; if (w<=tree[lc].mn) dochange(lc,w);else if (w>tree[lc].mx2&&w<tree[lc].mx) tree[lc].mx=w,tree[lc].tag=w; if (w<=tree[rc].mn) dochange(rc,w);else if (w>tree[rc].mx2&&w<tree[rc].mx) tree[rc].mx=w,tree[rc].tag=w; } } inline void insert1(int x,int l,int r,int l1,int r1,int w){ if (l1<=l&&r1>=r){doadd(x,w);return;} int mid=l+r>>1;pushdown(x); if (l1<=mid) insert1(lc,l,mid,l1,r1,w); if (r1>mid) insert1(rc,mid+1,r,l1,r1,w);update(x); } inline void modify(int x,int l,int r,int l1,int r1,int w){ if (tree[x].mx<=w) return;if (l!=r) pushdown(x); if(l1<=l&&r1>=r){ if (w<=tree[x].mn) {dochange(x,w);return;}int mid=l+r>>1; if (w>tree[x].mx2) {tree[x].mx=w;tree[x].tag=w;return;} modify(lc,l,mid,l1,r1,w);modify(rc,mid+1,r,l1,r1,w);update(x);return; }int mid=l+r>>1; if (l1<=mid) modify(lc,l,mid,l1,r1,w); if (r1>mid) modify(rc,mid+1,r,l1,r1,w);update(x); } inline bool query(int x,int l,int r,int l1,int r1){ if (l1<=l&&r1>=r){ if(tree[x].mx>min1) return 0; min1=tree[x].mn;return tree[x].flag; }int mid=l+r>>1;pushdown(x); if (l1<=mid) if (!query(lc,l,mid,l1,r1)) return 0; if (r1>mid) if (!query(rc,mid+1,r,l1,r1)) return 0; return 1; } int main(){ //freopen("t3.in","r",stdin); // freopen("t3.out","w",stdout); n=read();m=read();build(1,1,n); for (int i=1;i<=m;++i){ int op=read(),l=read(),r=read(); if (op==1) insert1(1,1,n,l,r,read()); if (op==2) modify(1,1,n,l,r,read()); if (op==3) {min1=inf;if (!query(1,1,n,l,r)) printf("%d\n",r-l+1);else puts("1");} } return 0; }
相关文章推荐
- BJ 集训测试10 城市
- BJ 集训测试12 coin
- BJ 集训测试13 平行
- BJ 集训测试6 求和
- BJ 集训测试7 A模型
- BJ 集训测试9 Problem C King
- BJ 集训8 测试 B 新访问计划
- BJ 集训测试14 pow
- BJ 集训测试9 draw
- BJ 集训测试11 flow
- BJ 集训测试11 level&& codeforces 700E
- BJ 集训测试12 同构
- BJ 集训测试14 bird
- BJ 集训测试7 Mythological VII
- BJ 集训测试13 钢琴
- BJ 集训测试11 捕鱼
- BJ 集训测试8 Problem C 插线板
- 暑假集训中期测试 Problem G: 维护序列 (线段树)
- 基础算法测试——生成一个1-10之间的随机整数组合
- 敏捷测试(10)--验收测试执行