zoukankan      html  css  js  c++  java
  • hdu

    题目原文废话太多太多太多,我就不copyandpaste到这里啦。。发个链接吧题目

    题目意思就是:P  l  r  c  将区间 [l ,r]上的颜色变成c    Q  l r 就是打印出区间[l,r]中所有的颜色,并且要升序排列出来,注意最坑的就是各个区间的颜色初始化为2,这个条件竟然夹杂在那又长又臭的题目的某个角落里面!!

    比赛的时候思路是有的,并且也能想到用set来撸,哎,对set的用法太挫逼了,写线段树又写得太挫逼了,后来补回这道题的时候,才发现其实是一道非常常规的线段树,所以最近给自己留了20道线段树慢慢刷,主要是能够更加熟练地写出线段树的模板,因为我发觉之前只是看得懂别人写的线段树的代码,却很少完全靠自己去敲出来,今天在补这道题的时候依然wa了很多次,最终才发现在query的那里忘记PushDown了  QAQ,废话少说 直接贴代码:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <queue>
     4 #include <set>
     5 #include <cstring>
     6 using namespace std;
     7 #define lson l,m,rt<<1
     8 #define rson m+1,r,rt<<1|1
     9 const int maxn = 1001111;
    10 set<int> ans;
    11 int SIZE;
    12 int sum[maxn<<2];
    13 void PushDown(int rt){
    14     if(sum[rt]){
    15         sum[rt<<1] = sum[rt];
    16         sum[rt<<1|1] = sum[rt];
    17         sum[rt] = 0;
    18     }
    19 }
    20 void build(int l,int r,int rt){
    21     if(l == r){
    22         sum[rt] = 2;return;
    23     }
    24     int m = (l + r) >>1;
    25     build(lson);
    26     build(rson);
    27     return ;
    28 }
    29 void update(int L,int R,int c,int l,int r,int rt){
    30     if(L <= l&&r <= R){
    31         sum[rt] = c;
    32         return ;
    33     }
    34     int m = (l + r)>>1;
    35     PushDown(rt);
    36     if(L <= m) update(L,R,c,lson);
    37 
    38     if(m <  R) update(L,R,c,rson);
    39     return ;
    40 }
    41 void query(int L,int R,int l,int r,int rt){
    42     //if(rt > SIZE) return;
    43     if(L <= l&&r <= R&&sum[rt]){
    44         ans.insert(sum[rt]);
    45         return ;
    46     }
    47     PushDown(rt);
    48     int m = (l + r)>>1;
    49     if(L <= m) query( L, R,lson);
    50     if(m <  R) query( L, R,rson);
    51     return;
    52 }
    53 void print(){
    54     set<int>::iterator it;
    55     it = ans.begin();
    56     cout<<*it;
    57     ans.erase(it);
    58     for(it = ans.begin();it != ans.end();++it)
    59         printf(" %d",*it);
    60         puts("");
    61 }
    62 void print_debug(){
    63     cout<<"sum: "<<endl;
    64     for(int i = 1;i <= 20;i++)
    65         cout<<sum[i]<<" ";
    66         puts("");
    67 }
    68 int main(){
    69     int N,Q,a,b,c;
    70     char ope[3];
    71     while(~scanf("%d%d",&N,&Q)&&(N+Q)){
    72         SIZE = (N+1)*N/2;
    73         memset(sum,0,sizeof(sum));
    74         build(1,N,1);
    75         while(Q--){
    76             scanf("%s",ope);
    77             if(ope[0] == 'Q'){
    78                 scanf("%d%d",&a,&b);
    79                 ans.clear();
    80                 query(a,b,1,N,1);
    81                 print();
    82             }else{
    83                 scanf("%d%d%d",&a,&b,&c);
    84                 update(a,b,c,1,N,1);
    85                 //print_debug();
    86             }
    87         }
    88     }
    89     return 0;
    90 }
    View Code

    然后我又看到了另一份比较好玩的代码,是通过巧妙的位移运算来表示的,恩 感觉挺好的   链接请点击~

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 
      6 #define lson l , mid , rt << 1
      7 #define rson mid + 1 , r , rt << 1 | 1
      8 #define LL int
      9 
     10 const int maxn = 1100017;
     11 LL add[maxn<<2];
     12 LL sum[maxn<<2];
     13 void PushUp(int rt)
     14 {
     15     //把当前结点的信息更新到父结点
     16     sum[rt] = sum[rt<<1] | sum[rt<<1|1];//总共的颜色
     17 }
     18 void PushDown(int rt,int m)
     19 {
     20     if(add[rt])
     21     {
     22         add[rt<<1] = add[rt];
     23         add[rt<<1|1] = add[rt];
     24         sum[rt<<1] = add[rt] ;
     25         sum[rt<<1|1] = add[rt] ;
     26         add[rt] = 0;//将标记向儿子节点移动后,父节点的延迟标记去掉
     27         //传递后,当前节点标记域清空
     28     }
     29 }
     30 void build(int l,int r,int rt)
     31 {
     32     add[rt] = 0;//初始化为所有结点未被标记
     33     if (l == r)
     34     {
     35         sum[rt]=2;//初始颜色为2
     36         return ;
     37     }
     38     int mid = (l + r) >> 1;
     39     build(lson);
     40     build(rson);
     41     PushUp(rt);
     42 }
     43 void update(int L,int R,int c,int l,int r,int rt)
     44 {
     45     if (L <= l && r <= R)
     46     {
     47         add[rt] =1<<(c-1);//位运算左移表示有某种颜色
     48         sum[rt] =1<<(c-1);
     49         return ;
     50     }
     51     PushDown(rt , r - l + 1);//----延迟标志域向下传递
     52     int mid = (l + r) >> 1;
     53     if (L <= mid)
     54         update(L , R , c , lson);//更新左儿子
     55     if (mid < R)
     56         update(L , R , c , rson);//更新右儿子
     57     PushUp(rt);
     58 }
     59 LL query(int L,int R,int l,int r,int rt)
     60 {
     61     if (L <= l && r <= R)
     62     {
     63         return sum[rt];
     64     }
     65     //要取rt子节点的值时,也要先把rt的延迟标记向下移动
     66     PushDown(rt , r - l + 1);
     67     int mid = (l + r) >> 1;
     68     LL ret = 0;
     69     if (L <= mid)
     70         ret |= query(L , R , lson);
     71     if (mid < R)
     72         ret |= query(L , R , rson);
     73     return ret;
     74 }
     75 int main()
     76 {
     77     int N , Q;
     78     int a , b , c;
     79     while(scanf("%d%d",&N,&Q))
     80     {
     81         if(N==0 && Q==0)
     82             break;
     83         build(1 , N , 1);//建树
     84         while(Q--)//Q为询问次数
     85         {
     86             char op[2];
     87             scanf("%s",op);
     88             if(op[0] == 'Q')//Q为询问次数
     89             {
     90                 scanf("%d%d",&a,&b);
     91                 LL tt=query(a , b , 1 , N , 1);
     92                 LL flag = 0;
     93                 for(int i=1; i<=30; i++)
     94                 {
     95                     if(tt>>(i-1)&1 && flag==0)
     96                     {
     97                         printf("%d",i);
     98                         flag = 1;
     99                     }
    100                     else if(tt>>(i-1)&1)
    101                         printf(" %d",i);
    102                 }
    103                 printf("
    ");
    104             }
    105             else
    106             {
    107                 scanf("%d%d%d",&a,&b,&c);
    108                 update(a , b , c , 1 , N , 1);
    109             }
    110         }
    111     }
    112     return 0;
    113 }
    View Code
    额 继续努力吧 骚年~~~
  • 相关阅读:
    高盛、沃尔玛 题做出来还挂了的吐槽
    amazon师兄debrief
    到所有人家距离之和最短的中点 296. Best Meeting Point
    问问题没人回答的情况怎么办终于有解了
    找名人 277. Find the Celebrity
    数组生存游戏 289. Game of Life
    547. Number of Provinces 省份数量
    428. Serialize and Deserialize Nary Tree 序列化、反序列化n叉树
    alias别名简介和使用
    面试官:线程池执行过程中遇到异常会发生什么,怎样处理? Vincent
  • 原文地址:https://www.cnblogs.com/jusonalien/p/3993035.html
Copyright © 2011-2022 走看看