zoukankan      html  css  js  c++  java
  • cdoj 1259 线段树+bitset 区间更新/查询

    Description

    昊昊喜欢运动

    N天内会参加M种运动(每种运动用一个[1,m]的整数表示)

    现在有Q个操作,操作描述如下

    • 昊昊把第l天到第r天的运动全部换成了x(x[1,m])
    • 问昊昊第l天到第r天参加了多少种不同的运动

    Input

    输入两个数NM (1N1051M100);

    输入N个数ai(ai[1,m])表示在第i天昊昊做了第ai类型的运动;

    输入一个数Q(1Q105);

    输入Q行 每行描述以下两种操作

    • 形如M l r x,表示昊昊把第l天到第r天的运动全部换成了x(x[1,m])
    • 形如Q l r,表示昊昊想知道他第l天到第r天参加了多少种不同的运动

    Output

    对于所有的Q操作,每一行输出一个数 表示昊昊在第l天到第r天一共做了多少种活动

    Sample Input

    5 3 
    1 2 3 2 3 

    Q 1 4 
    Q 2 4 
    M 5 5 2 
    Q 1 5

    Sample Output



    3

    题意:中文题意
     
    题解:线段树+bitset
     bitset记录运动的种类 bitset的用法 姿势涨  
     bitset<110> sum 
     
     (sum.reset() 全部置为0 )
     (sum.count()计算为1的位数) 
     (sum[x]=1 第x位赋为1)
     坑点: 千万不要直接复制样例 直接复制会很坑 orzzzz
          getchar()的问题  re多次   太菜了...
                      
      1 /******************************
      2 code by drizzle
      3 blog: www.cnblogs.com/hsd-/
      4 ^ ^    ^ ^
      5  O      O
      6 ******************************/
      7 //#include<bits/stdc++.h>
      8 #include<iostream>
      9 #include<cstring>
     10 #include<cmath>
     11 #include<cstdio>
     12 #include<bitset>
     13 //#define ll long long
     14 #define mod 1000000007
     15 #define PI acos(-1.0)
     16 using namespace std;
     17 struct node
     18 {
     19     int l,r;
     20     int add;
     21     bitset<110> sum;
     22 } tree[2000005];
     23 int n,m;
     24 int exm;
     25 int l1,r1,x;
     26 int q;
     27 char judge;
     28 void buildtree(int root,int left,int right)
     29 {
     30     tree[root].l=left;
     31     tree[root].r=right;
     32     tree[root].add=0;
     33     if(left==right)
     34     {
     35         tree[root].sum.reset();
     36         scanf("%d",&exm);
     37         tree[root].sum[exm]=1;
     38         return ;
     39     }
     40     int mid=(left+right)>>1;
     41     buildtree(root<<1,left,mid);
     42     buildtree(root<<1|1,mid+1,right);
     43     tree[root].sum=tree[root<<1].sum|tree[root<<1|1].sum;//按位或得到新的运动种类
     44 }
     45 void pushdown(int root)
     46 {
     47     if(tree[root].add==0)
     48         return ;
     49     tree[root<<1].sum.reset();
     50     tree[root<<1|1].sum.reset();
     51     tree[root<<1].sum[tree[root].add]=1;
     52     tree[root<<1|1].sum[tree[root].add]=1;
     53     tree[root<<1].add=tree[root].add;//注意延迟标记也要往下传
     54     tree[root<<1|1].add=tree[root].add;
     55     tree[root].add=0;
     56 }
     57 void updata(int root,int left,int right,int c)
     58 {
     59     if(tree[root].l==left&&tree[root].r==right)
     60     {
     61         tree[root].sum.reset();//全部置零
     62         tree[root].add=c;
     63         tree[root].sum[c]=1;//整个区间只有c运动
     64         return ;
     65     }
     66     pushdown(root);//lazy 延迟标记
     67     int mid=(tree[root].l+tree[root].r)>>1;
     68     if(right<=mid)
     69         updata(root<<1,left,right,c);
     70     else
     71     {
     72         if(left>mid)
     73             updata(root<<1|1,left,right,c);
     74         else
     75         {
     76             updata(root<<1,left,mid,c);
     77             updata(root<<1|1,mid+1,right,c);
     78         }
     79     }
     80     tree[root].sum=tree[root<<1].sum|tree[root<<1|1].sum;
     81 }
     82 bitset<110> query(int root,int left,int right)
     83 {
     84     if(tree[root].l==left&&tree[root].r==right)
     85     {
     86         return  tree[root].sum;
     87     }
     88     pushdown(root);
     89     int mid=(tree[root].l+tree[root].r)>>1;
     90     if(right<=mid)
     91         return query(root<<1,left,right);
     92     else
     93     {
     94         if(left>mid)
     95             return query(root<<1|1,left,right);
     96         else
     97             return query(root<<1,left,mid)|query(root<<1|1,mid+1,right);
     98     }
     99 }
    100 int main()
    101 {
    102     while(scanf("%d %d",&n,&m)!=EOF)
    103     {
    104         buildtree(1,1,n);
    105         scanf("%d",&q);
    106         getchar();
    107         for(int i=1; i<=q; i++)
    108         {
    109             scanf("%c",&judge);
    110             if(judge=='Q')
    111             {
    112                 scanf("%d %d",&l1,&r1);
    113                 printf("%d
    ",query(1,l1,r1).count());
    114             }
    115             else
    116             {
    117                 scanf("%d %d %d",&l1,&r1,&x);
    118                 updata(1,l1,r1,x);
    119             }
    120             getchar();//坑点
    121         }
    122     }
    123     return 0;
    124 }
     
  • 相关阅读:
    《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第八章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
    我的superui开源后台bootstrap开发框架
    LayoutInflater 总结
    Android屏幕分辨率概念(dp、dip、dpi、sp、px)
    android studio安装问题
  • 原文地址:https://www.cnblogs.com/hsd-/p/5713167.html
Copyright © 2011-2022 走看看