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
    额 继续努力吧 骚年~~~
  • 相关阅读:
    i3wm 入门
    install kali on my x200
    Linux下pn532板子测试学校水卡
    Linux下常用工具
    未能加载文件或程序集"Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad
    SqlServer 日期函数
    asp.net 网站部署出错-未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
    win7中未加载类型“System.ServiceModel.Activation.HttpModule”
    ASP.NET开发工具用到的密匙与注意事项
    TCP/TP 三次握手
  • 原文地址:https://www.cnblogs.com/jusonalien/p/3993035.html
Copyright © 2011-2022 走看看