hdu 5023 线段树延迟更新+状态压缩

/*
线段树延迟更新+状态压缩
*/
#include<stdio.h>
#define N  1100000
struct node {
 int x,y,yanchi,sum;
}a[N*4];
int lower[31];
void build(int t,int x,int y) {
a[t].x=x;
a[t].y=y;
a[t].yanchi=0;
if(x==y){
     a[t].sum=lower[1];
        return ;
}
int temp=t<<1;
int mid=(x+y)/2;
build(temp,x,mid);
build(temp+1,mid+1,y);
a[t].sum=a[temp].sum|a[temp+1].sum;
}
void inset(int t,int x,int y,int c) {
   //printf("%d %d %d\n",a[t].yanchi,a[t].x,a[t].y);
   if(a[t].x==x&&a[t].y==y) {
    a[t].yanchi=lower[c];
    a[t].sum=lower[c];//sum和yanchi都需要改变
  //  printf("%d %d %d\n",x,y,lower[c]);
    return ;
   }
   int temp=t*2;
   int mid=(a[t].x+a[t].y)/2;
   if(a[t].yanchi) {//如果区间a[t].x--a[t].y被操作过就赋给子区间
   a[temp].yanchi=a[t].yanchi;
   a[temp].sum=a[t].sum;
   a[temp+1].yanchi=a[t].yanchi;
   a[temp+1].sum=a[t].sum;
   a[t].yanchi=0;
   }
   if(x>mid)inset(temp+1,x,y,c);
   else
    if(y<=mid)inset(temp,x,y,c);
   else {
    inset(temp,x,mid,c);
    inset(temp+1,mid+1,y,c);
   }
  a[t].sum=a[temp].sum|a[temp+1].sum;
   return ;
}
int qury(int t,int x,int y) {
  //   printf("%d %d %d\n",a[t].yanchi,a[t].x,a[t].y);
  if(a[t].x==x&&a[t].y==y) {
  // printf("%d\n",a[t].sum);
    return a[t].sum;
  }
  int temp=t*2;
  int mid=(a[t].x+a[t].y)/2;
   if(a[t].yanchi) {//如果区间a[t].x--a[t].y被操作过就赋给子区间
   a[temp].yanchi=a[t].yanchi;
   a[temp].sum=a[t].sum;
   a[temp+1].yanchi=a[t].yanchi;
   a[temp+1].sum=a[t].sum;
   a[t].yanchi=0;
   }
  if(x>mid)
    return qury(temp+1,x,y);
  else if(y<=mid)
    return qury(temp,x,y);
  else
    return qury(temp,x,mid)|qury(temp+1,mid+1,y);
  a[t].sum=a[temp+1].sum|a[temp].sum;//更新
}
int main() {
  int n,m,i,j,k,ans;
  char s[10];
  lower[0]=1;
  for(i=1;i<=30;i++)
    lower[i]=lower[i-1]*2;
  while(scanf("%d%d",&n,&m),n||m) {
     build(1,1,n);
    while(m--) {
        scanf("%s",s);
        if(s[0]=='P') {
        scanf("%d%d%d",&i,&j,&k);
         inset(1,i,j,k-1);
        }
        if(s[0]=='Q') {
            scanf("%d%d",&i,&j);
            ans=qury(1,i,j);
         //  printf("%d\n",ans);
             k=0;
             for(i=0;i<30;i++)
             if(ans&lower[i]) {
                if(k)
                    printf(" ");
                printf("%d",i+1);
                k=1;
             } printf("\n");
        }
    }

  }
return 0;
}

时间: 2024-10-10 01:57:24

hdu 5023 线段树延迟更新+状态压缩的相关文章

HDU 5023 A Corrupt Mayor&#39;s Performance Art 线段树区间更新+状态压缩

Link:  http://acm.hdu.edu.cn/showproblem.php?pid=5023 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <string> 7 #include <cmath> 8 using namesp

POJ 2777 &amp;&amp; ZOJ 1610 &amp;&amp;HDU 1698 --线段树--区间更新

直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 -- 区间更新的话 分为 增减 或者 修改 主要就是个 laze 标记 就是延迟更新 对于区间更新的写法 一般是有2种 其一 仔细划分到每个细小的区间    另一 粗略划分 反正 ==我的代码里会给出2种写法 看自己喜好 hdu 1 //线段树 成段更新 ---> 替换 根结点的查询 2 3 #i

HDU 4302 线段树单点更新,维护区间最大最小值

http://acm.hdu.edu.cn/showproblem.php?pid=4302 Problem Description Holedox is a small animal which can be considered as one point. It lives in a straight pipe whose length is L. Holedox can only move along the pipe. Cakes may appear anywhere in the p

hdu 2795 线段树--点更新

http://acm.hdu.edu.cn/showproblem.php?pid=2795 多校的第一场和第三场都出现了线段树,比赛期间没做,,这两天先做几道热身下,然后31号之前把那两道多校的线段树都搞了,这是一道热身题 关键是建模: 首先一定看清楚题目构造的场景,看有什么特点--------会发现,如果尽量往左上放置的话,那么由于 the i-th announcement is a rectangle of size 1 * wi.,完全可以对h建立线段树,表示一行,结点里的l,r就表示

HDU 1394(线段树单点更新)

题意:就是给出一串数,当依次在将第一个数变为最后一个数的过程中,要你求它的最小逆序数. 思路:可以用树状数组和线段数做.这里我是用线段树做的.建的是一棵空树,然后每插入一个点之前,统计大于这个数的有多少个,直到所有的数都插入完成,就结果了逆序树的统计. 要得出答案主要是利用了一个结论,如果是0到n的排列,那么如果把第一个数放到最后,对于这个数列,逆序数是减少a[i],而增加n-1-a[i]的. #include<iostream> #include<cstring> #includ

hdu 3308 线段树单点更新 区间合并

http://acm.hdu.edu.cn/showproblem.php?pid=3308 学到两点: 1.以区间端点为开始/结束的最长......似乎在Dp也常用这种思想 2.分类的时候,明确标准逐层分类,思维格式: 条件一成立: { 条件二成立: { } else { } } else { 条件二成立: { } else { } } 上面的这种方式很清晰,如果直接想到那种情况iif(条件一 &条件二)就写,很容易出错而且把自己搞乱,或者情况不全,,,我就因为这WA了几次 3.WA了之后 ,

HDU 4578 线段树区间更新(确定区间操作的优先级)

HDU 4578 线段树区间更新 操作有: 区间所有数add(c) 区间所有数mul(c) 区间所有数set(c) 查询有: 区间所有数的p次方和(p>= 1 && p <= 3) 关键是区间更新的三种操作的优先级的确定清楚set>mul>add 关键是:down和update中对区间的更新操作是一回事,可以写成函数方便编程 //#pragma warning (disable: 4786) //#pragma comment (linker, "/STA

线段树延迟更新

title: 线段树延迟更新 date: 2018-10-10 18:50:49 tags: acm 算法 categories: ACM-线段树 概述 暑假集训的时候好多东西只学了个皮毛,,,对付模板题还能试试,,,但是一看一些稍难的一些题时,,,肯定单纯的套模板是不行得了,,,那样多没意思啊,,, 延迟更新之前就看到过,,,当初的映像就是在普通的线段树里加一个lazy,,,然后可以延迟更新区间,,,这在对区间整段的更新很有用,,,因为不用对更新区间的每一个点更新,,这样就能省下很多时间,,,

hdu 5023 线段树 区间 2014广东区域赛网赛

http://acm.hdu.edu.cn/showproblem.php?pid=5023 当时大一学弟15minAC 搞得我压力山大 给队友写了 今天重新做了下,题还是很水  但是因为pushdown的时候if(l==r)return没有写  WA了一次 感觉到现在,简单的线段树已经可以随意点写了,就是按照自己的理解写,别慌,错了按树的结构思考下重新写 查询不知道pushdown所有的会不会超时,我的还是区间的查询,凡是子区间被修改过的结点,该节点pushdown后 其co值都被我改为0 然