• 第7章 代码


    后缀数组

    poj 1743

    poj 3415

    poj 2758

    线段树

    poj 2828

     每个人依次插队, pos表示这个人会差到第pos个人的右边, 树状数组维护,开始的时候全置1,表示每个位置都有一个人,就是最终的状态,然后按照时间顺序 倒序处理.  先处理最后一个人, 二分出前n项和等于其pos+1的位置, 那么这个人就会在这个位置,  对于最后一个人, 他恰好在 pos位置, 然后最后一个人的位置确定了,  树状数组改位置清零, 状态就是除去这个人的状态, 然后处理倒数第二个人, 以此类推. 线段树有个比较巧妙的写法,3年前的工作了, 也贴一下吧. 虽然测试没快多少, 但是树状数组n*logn*logn,因为有二分, 线段树只有nlogn. 线段树结点存区间的和, 查询一个值时, 左儿子和如果足够,就走左边, 否则减去左边的和,剩余部分走右边,返回走到叶子结点的id.

    array

     1 //#define txtout
     2 //#define debug
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<stack>
    13 #include<queue>
    14 #include<set>
    15 #include<map>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double pi=acos(-1.0);
    20 const double eps=1e-8;
    21 const int inf=0x3f3f3f3f;
    22 const int M=2e5+10;
    23 class One_Tree_Array { ///一维树状数组
    24     static const int M=2e5+10; ///点的个数
    25     typedef int typev;
    26     typev a[M];
    27     int n;
    28 public:
    29     void init(int tn) { ///传入点数,点下标 1 开始
    30         n=tn;
    31         for(int i=0; i<=n; i++) a[i]=0;
    32     }
    33     int lowb(int t) {
    34         return t&(-t);
    35     }
    36     void add(int i,typev v) {
    37         for(; i<=n; a[i]+=v,i+=lowb(i));
    38     }
    39     typev sum(int i) {
    40         typev s=0;
    41         for(; i>0; s+=a[i],i-=lowb(i));
    42         return s;
    43     }
    44 } tree;
    45 int n;
    46 struct Q {
    47     int pos,val;
    48 } p[M];
    49 int answer[M];
    50 int Binary(int x){
    51     int L=0,R=n-1,result=0;
    52     while(L<=R){
    53         int mid=(L+R)>>1;
    54         if(tree.sum(mid+1)>=x){
    55             result=mid;
    56             R=mid-1;
    57         }
    58         else{
    59             L=mid+1;
    60         }
    61     }
    62     return result;
    63 }
    64 void solve() {
    65     tree.init(n);
    66     for(int i=1;i<=n;i++){
    67         tree.add(i,1);
    68     }
    69     for(int i=n-1;i>=0;i--){
    70         int to=Binary(p[i].pos+1);
    71         answer[to]=p[i].val;
    72         tree.add(to+1,-1);
    73     }
    74 }
    75 int main() {
    76 #ifdef txtout
    77     freopen("in.txt","r",stdin);
    78     freopen("out.txt","w",stdout);
    79 #endif // txtout
    80     while(~scanf("%d",&n)) {
    81         for(int i=0; i<n; i++) {
    82             scanf("%d%d",&p[i].pos,&p[i].val);
    83         }
    84         solve();
    85         for(int i=0; i<n; i++) {
    86             if(i) putchar(' ');
    87             printf("%d",answer[i]);
    88         }
    89         puts("");
    90     }
    91     return 0;
    92 }
    View Code

    segment tree

     1 #include<cstdio>
     2 const int M=200010;
     3 int tree[M<<2];
     4 int ans[M];
     5 int pos[M];
     6 int val[M];
     7 void build(int L,int R,int rt){
     8     tree[rt]=R-L+1;
     9     if(L!=R){
    10         int mid=(L+R)>>1;
    11         build(L,mid,rt<<1);
    12         build(mid+1,R,rt<<1|1);
    13     }
    14 }
    15 int update(int x,int L,int R,int rt){
    16     tree[rt]--;
    17     if(L==R){
    18         return L;
    19     }
    20     int mid=(L+R)>>1;
    21     if(tree[rt<<1]>=x){
    22         return update(x,L,mid,rt<<1);
    23     }
    24     else{
    25         x-=tree[rt<<1];
    26         return update(x,mid+1,R,rt<<1|1);
    27     }
    28 }
    29 int main(){
    30     int n;
    31     while(~scanf("%d",&n)){
    32         build(1,n,1);
    33         for(int i=1;i<=n;i++){
    34             scanf("%d%d",&pos[i],&val[i]);
    35         }
    36         for(int i=n;i>=1;i--){
    37             int k=update(pos[i]+1,1,n,1);
    38             ans[k]=val[i];
    39         }
    40         for(int i=1;i<=n;i++){
    41             printf("%d ",ans[i]);
    42         }
    43         puts("");
    44     }
    45     return 0;
    46 }
    View Code

    poj 3468

    区间+值,区间求和,线段树区间更新基础。

      1 //#define debug
      2 //#define txtout
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<stack>
     13 #include<queue>
     14 #include<set>
     15 #include<map>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double eps=1e-8;
     20 const double pi=acos(-1.0);
     21 const int inf=0x3f3f3f3f;
     22 const int M=1e5+10;
     23 class SegmentTree{
     24     #define lrrt int L,int R,int rt
     25     #define iall 1,n,1
     26     #define imid int mid=(L+R)>>1
     27     #define lson L,mid,rt<<1
     28     #define rson mid+1,R,rt<<1|1
     29     static const int MV=1e5+10;
     30     struct T{
     31         LL sum,lazy;
     32     }tree[MV<<2];
     33     int n;
     34     void build(lrrt,int a[]){
     35         tree[rt].lazy=0;
     36         if(L==R){
     37             tree[rt].sum=a[L];
     38             return ;
     39         }
     40         imid;
     41         build(lson,a);
     42         build(rson,a);
     43         pushup(rt);
     44     }
     45     void pushup(int rt){
     46         tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
     47     }
     48     void pushdown(int mid,lrrt){
     49         if(tree[rt].lazy){
     50             tree[rt<<1].sum+=tree[rt].lazy*(mid-L+1);
     51             tree[rt<<1|1].sum+=tree[rt].lazy*(R-mid);
     52             tree[rt<<1].lazy+=tree[rt].lazy;
     53             tree[rt<<1|1].lazy+=tree[rt].lazy;
     54             tree[rt].lazy=0;
     55         }
     56     }
     57     void update(int x,int y,LL z,lrrt){
     58         if(x<=L&&R<=y){
     59             tree[rt].sum+=(R-L+1)*z;
     60             tree[rt].lazy+=z;
     61             return ;
     62         }
     63         imid;
     64         pushdown(mid,L,R,rt);
     65         if(mid>=x) update(x,y,z,lson);
     66         if(mid<y)  update(x,y,z,rson);
     67         pushup(rt);
     68     }
     69     LL querySum(int x,int y,lrrt){
     70         if(x<=L&&R<=y) return tree[rt].sum;
     71         imid;
     72         pushdown(mid,L,R,rt);
     73         LL sum=0;
     74         if(mid>=x) sum+=querySum(x,y,lson);
     75         if(mid<y)  sum+=querySum(x,y,rson);
     76         return sum;
     77     }
     78 public:
     79     void init(int tn,int a[]){
     80         n=tn;
     81         build(iall,a);
     82     }
     83     void update(int x,int y,LL z){
     84         update(x,y,z,iall);
     85     }
     86     LL querySum(int x,int y){
     87         return querySum(x,y,iall);
     88     }
     89 }st;
     90 int n,m;
     91 int a[M];
     92 vector<LL> answer;
     93 struct Q{
     94     int x,y,z;
     95     char type[4];
     96 }q[M];
     97 void solve(){
     98     st.init(n,a);
     99     answer.clear();
    100     for(int i=0;i<m;i++){
    101         if(q[i].type[0]=='Q'){
    102             answer.push_back(st.querySum(q[i].x,q[i].y));
    103             continue;
    104         }
    105         st.update(q[i].x,q[i].y,q[i].z);
    106     }
    107 }
    108 int main() {
    109 #ifdef txtout
    110     freopen("in.txt","r",stdin);
    111     freopen("out.txt","w",stdout);
    112 #endif // txtout
    113     while(~scanf("%d%d",&n,&m)) {
    114         for(int i=1; i<=n; i++) {
    115             scanf("%d",&a[i]);
    116         }
    117         for(int i=0;i<m;i++){
    118             scanf("%s%d%d",q[i].type,&q[i].x,&q[i].y);
    119             if(q[i].type[0]=='C'){
    120                 scanf("%d",&q[i].z);
    121             }
    122         }
    123         solve();
    124         for(int i=0; i<answer.size(); i++) {
    125             printf("%I64d
    ",answer[i]);
    126         }
    127     }
    128     return 0;
    129 }
    View Code

    poj 2528

    区间赋值,查询有多少个不同的值。坐标较大需要离散化。线段树区间赋值,单点查询基础。

      1 //#define debug
      2 //#define txtout
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<stack>
     13 #include<queue>
     14 #include<set>
     15 #include<map>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double eps=1e-8;
     20 const double pi=acos(-1.0);
     21 const int inf=0x3f3f3f3f;
     22 const int M=1e4+10;
     23 class SegmentTree{
     24     #define lrrt int L,int R,int rt
     25     #define iall 1,n,1
     26     #define imid int mid=(L+R)>>1
     27     #define lson L,mid,rt<<1
     28     #define rson mid+1,R,rt<<1|1
     29     static const int MV=1e5+10;
     30     struct T{
     31         int sum,cover;
     32     }tree[MV<<2];
     33     int n;
     34     void build(lrrt){
     35         tree[rt].sum=0;
     36         tree[rt].cover=0;
     37         if(L==R) return ;
     38         imid;
     39         build(lson);
     40         build(rson);
     41     }
     42     void pushdown(int mid,lrrt){
     43         if(tree[rt].cover){
     44             tree[rt<<1].cover=tree[rt].cover;
     45             tree[rt<<1|1].cover=tree[rt].cover;
     46             tree[rt<<1].sum=tree[rt].cover*(mid-L+1);
     47             tree[rt<<1|1].sum=tree[rt].cover*(R-mid);
     48             tree[rt].cover=0;
     49         }
     50     }
     51     void change(int x,int y,int z,lrrt){
     52         if(x<=L&&R<=y){
     53             tree[rt].sum=(R-L+1)*z;
     54             tree[rt].cover=z;
     55             return ;
     56         }
     57         imid;
     58         pushdown(mid,L,R,rt);
     59         if(mid>=x) change(x,y,z,lson);
     60         if(mid<y)  change(x,y,z,rson);
     61     }
     62     int querySum(int x,int y,lrrt){
     63         if(x<=L&&R<=y) return tree[rt].sum;
     64         imid;
     65         pushdown(mid,L,R,rt);
     66         int sum=0;
     67         if(mid>=x) sum+=querySum(x,y,lson);
     68         if(mid<y)  sum+=querySum(x,y,rson);
     69         return sum;
     70     }
     71 public:
     72     void init(int tn){
     73         n=tn;
     74         build(iall);
     75     }
     76     void change(int x,int y,int z){
     77         change(x,y,z,iall);
     78     }
     79     int querySum(int x,int y){
     80         return querySum(x,y,iall);
     81     }
     82 }st;
     83 int n;
     84 struct A{
     85     int x,y;
     86 }a[M];
     87 map<int,int> mp;
     88 vector<int> buffer;
     89 void init_map(){
     90     buffer.clear();
     91     for(int i=0;i<n;i++){
     92         buffer.push_back(a[i].x);
     93         buffer.push_back(a[i].y);
     94     }
     95     sort(buffer.begin(),buffer.end());
     96     mp.clear();
     97     int id=1;
     98     for(int i=0;i<buffer.size();i++){
     99         if(mp.count(buffer[i])) continue;
    100         mp[buffer[i]]=id++;
    101     }
    102 }
    103 int solve(){
    104     init_map();
    105     int total=mp.size();
    106     st.init(total);
    107     for(int i=0;i<n;i++){
    108         st.change(mp[a[i].x],mp[a[i].y],i+1);
    109     }
    110     buffer.clear();
    111     for(int i=1;i<=total;i++){
    112         buffer.push_back(st.querySum(i,i));
    113     }
    114     sort(buffer.begin(),buffer.end());
    115     buffer.push_back(-1);
    116     int answer=0;
    117     for(int i=0;i+1<buffer.size();i++){
    118         if(buffer[i]!=buffer[i+1]){
    119             answer++;
    120         }
    121     }
    122     return answer;
    123 }
    124 int main(){
    125     #ifdef txtout
    126     freopen("in.txt","r",stdin);
    127     freopen("out.txt","w",stdout);
    128     #endif // txtout
    129     int t;
    130     while(~scanf("%d",&t)){
    131         while(t--){
    132             scanf("%d",&n);
    133             for(int i=0;i<n;i++){
    134                 scanf("%d%d",&a[i].x,&a[i].y);
    135             }
    136             printf("%d
    ",solve());
    137         }
    138     }
    139     return 0;
    140 }
    View Code

     上面代码虽能ac,但实际上有错,不知道poj样例水了? 15 ,12,45,这一组答案应是3, 上面代码返回2, 原因是离散化有问题. 下面给13年的代码, 离散化的时候注意两个点不相邻的时候, 离散化后也应该不相邻,增加一个中间值就行.

      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 const int M=10000010;
      5 int myset[M];
      6 int mymap[M];
      7 bool v[M];
      8 int lazy[M<<2];
      9 struct G{
     10     int x,y;
     11 }g[10010];
     12 void build(int L,int R,int rt){
     13     lazy[rt]=0;
     14     if(L==R){
     15         return ;
     16     }
     17     int mid=(L+R)>>1;
     18     build(L,mid,rt<<1);
     19     build(mid+1,R,rt<<1|1);
     20 }
     21 void pushdown(int rt){
     22     if(lazy[rt]){
     23         if(lazy[rt<<1]<lazy[rt])
     24             lazy[rt<<1]=lazy[rt];
     25         if(lazy[rt<<1|1]<lazy[rt])
     26             lazy[rt<<1|1]=lazy[rt];
     27         lazy[rt]=0;
     28     }
     29 }
     30 void update(int x,int y,int val,int L,int R,int rt){
     31     if(x<=L&&R<=y){
     32         if(lazy[rt]<val)
     33             lazy[rt]=val;
     34     }
     35     else{
     36         int mid=(L+R)>>1;
     37         pushdown(rt);
     38         if(mid>=x)
     39             update(x,y,val,L,mid,rt<<1);
     40         if(mid<y)
     41             update(x,y,val,mid+1,R,rt<<1|1);
     42     }
     43 }
     44 void get(int L,int R,int rt){
     45     if(L==R){
     46         v[lazy[rt]]=true;
     47     }
     48     else{
     49         int mid=(L+R)>>1;
     50         pushdown(rt);
     51         get(L,mid,rt<<1);
     52         get(mid+1,R,rt<<1|1);
     53     }
     54 }
     55 int main(){
     56     int t,n,m;
     57     while(~scanf("%d",&t)){
     58         while(t--){
     59             scanf("%d",&m);
     60             int ls=0;
     61             for(int i=0;i<m;i++){
     62                 scanf("%d%d",&g[i].x,&g[i].y);
     63                 myset[ls++]=g[i].x;
     64                 myset[ls++]=g[i].y;
     65             }
     66             sort(myset,myset+ls);
     67             int id=0;
     68             myset[ls]=0;
     69             for(int i=0;i<ls;i++){
     70                 if(myset[i]!=myset[i+1]){
     71                     myset[id++]=myset[i];
     72                 }
     73             }
     74             ls=id;
     75             myset[ls]=0;
     76             n=1;
     77             for(int i=0;i<ls;i++,n++){
     78                 mymap[myset[i]]=n;
     79                 if(myset[i+1]!=myset[i]+1){
     80                     n++;
     81                 }
     82             }
     83             build(1,n,1);
     84             int val=1;
     85             for(int i=0;i<m;i++,val++){
     86                 update(mymap[g[i].x],mymap[g[i].y],val,1,n,1);
     87             }
     88             for(int i=1;i<=val;i++){
     89                 v[i]=false;
     90             }
     91             get(1,n,1);
     92             int ans=0;
     93             for(int i=1;i<=val;i++){
     94                 if(v[i]){
     95                     ans++;
     96                 }
     97             }
     98             printf("%d
    ",ans);
     99         }
    100     }
    101     return 0;
    102 }
    View Code

    poj 3667

    酒店有n个房间,开始都空, 每次来个团, 她们要求要连续的k个房间,不存在输出0, 存在就把起点最靠左边的输出,并占用这一段房间.  线段树, 一开始全1 ,表示每个房间都可用, 更新就是区间赋值1或0.  

    线段树4个值,big是该区间最大连续子段的长度,  left是区间左端点为起点的最长连续子段长度,  right是右端点为终点,  cover是区间赋值的延迟标记.  一个区间最长可能有3种情况 ,完全在左儿子, 完全在右儿子, 左儿子的right + 右儿子的left.

      1 //#define txtout
      2 //#define debug
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<stack>
     13 #include<queue>
     14 #include<set>
     15 #include<map>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double pi=acos(-1.0);
     20 const double eps=1e-8;
     21 const int inf=0x3f3f3f3f;
     22 const int M=5e4+10;
     23 class SegmentTree{
     24     #define lrrt int L,int R,int rt
     25     #define iall 1,n,1
     26     #define imid int mid=(L+R)>>1
     27     #define lson L,mid,rt<<1
     28     #define rson mid+1,R,rt<<1|1
     29     static const int MV=5e4+10;
     30     struct T{
     31         int big,left,right,cover;
     32     }tree[MV<<2];
     33     int n;
     34     void pushup(int mid,lrrt){
     35         tree[rt].big=max(tree[rt<<1].big,tree[rt<<1|1].big);
     36         tree[rt].big=max(tree[rt].big,tree[rt<<1].right+tree[rt<<1|1].left);
     37         tree[rt].left=tree[rt<<1].left;
     38         if(tree[rt].left==mid-L+1){
     39             tree[rt].left+=tree[rt<<1|1].left;
     40         }
     41         tree[rt].right=tree[rt<<1|1].right;
     42         if(tree[rt].right==R-mid){
     43             tree[rt].right+=tree[rt<<1].right;
     44         }
     45     }
     46     void build(lrrt){
     47         tree[rt].cover=-1;
     48         if(L==R){
     49             tree[rt].big=1;
     50             tree[rt].left=1;
     51             tree[rt].right=1;
     52             return ;
     53         }
     54         imid;
     55         build(lson);
     56         build(rson);
     57         pushup(mid,L,R,rt);
     58     }
     59     void pushdown(int mid,lrrt){
     60         if(tree[rt].cover!=-1){
     61             tree[rt<<1].cover=tree[rt].cover;
     62             tree[rt<<1|1].cover=tree[rt].cover;
     63             int lvalue=(mid-L+1)*tree[rt].cover;
     64             tree[rt<<1].big=lvalue;
     65             tree[rt<<1].left=lvalue;
     66             tree[rt<<1].right=lvalue;
     67             int rvalue=(R-mid)*tree[rt].cover;
     68             tree[rt<<1|1].big=rvalue;
     69             tree[rt<<1|1].left=rvalue;
     70             tree[rt<<1|1].right=rvalue;
     71             tree[rt].cover=-1;
     72         }
     73     }
     74     void update(int x,int y,int z,lrrt){
     75         if(x<=L&&R<=y){
     76             tree[rt].cover=z;
     77             int value=(R-L+1)*z;
     78             tree[rt].big=value;
     79             tree[rt].left=value;
     80             tree[rt].right=value;
     81             return ;
     82         }
     83         imid;
     84         pushdown(mid,L,R,rt);
     85         if(mid>=x) update(x,y,z,lson);
     86         if(mid<y)  update(x,y,z,rson);
     87         pushup(mid,L,R,rt);
     88     }
     89     int query(int x,lrrt){
     90         if(L==R) return L;
     91         imid;
     92         pushdown(mid,L,R,rt);
     93         if(tree[rt<<1].big>=x) return query(x,lson);
     94         if(tree[rt<<1].right+tree[rt<<1|1].left>=x) return mid-tree[rt<<1].right+1;
     95         return query(x,rson);
     96     }
     97 public:
     98     void init(int tn){
     99         n=tn;
    100         build(iall);
    101     }
    102     int query(int len){
    103         if(tree[1].big<len) return 0;
    104         return query(len,iall);
    105     }
    106     void update(int x,int y,int z){
    107         update(x,y,z,iall);
    108     }
    109 }st;
    110 int n,m;
    111 struct Q{
    112     int type,x,y;
    113 }q[M];
    114 vector<int> answer;
    115 void solve(){
    116     st.init(n);
    117     answer.clear();
    118     for(int i=0;i<m;i++){
    119         if(q[i].type==1){
    120             int result=st.query(q[i].x);
    121             answer.push_back(result);
    122             if(result){
    123                 st.update(result,result+q[i].x-1,0);
    124             }
    125             continue;
    126         }
    127         st.update(q[i].x,q[i].x+q[i].y-1,1);
    128     }
    129 }
    130 int main() {
    131 #ifdef txtout
    132     freopen("in.txt","r",stdin);
    133     freopen("out.txt","w",stdout);
    134 #endif // txtout
    135     while(~scanf("%d%d",&n,&m)) {
    136         for(int i=0; i<m; i++) {
    137             scanf("%d%d",&q[i].type,&q[i].x);
    138             if(q[i].type==2){
    139                 scanf("%d",&q[i].y);
    140             }
    141         }
    142         solve();
    143         for(int i=0; i<answer.size(); i++) {
    144             printf("%d
    ",answer[i]);
    145         }
    146     }
    147     return 0;
    148 }
    View Code

    处理特殊图

    poj 1041 uva302

    poj 2337 zoj 1919

    uva 216

    uva 10944

    poj 1776 zoj 2359 uva 2954

    poj 1419 uva 193

    poj 1144 zoj 1311 uva 315

    poj 3352

    相关题库

    poj 2774

    poj 3261

    poj 2777

    一开始n个点都是颜色1,  操作会把某一个区间的颜色都变成 z,  查询某个区间有多少种不同颜色. 现在的写法, 因为颜色只有30位, 一开始开了30个线段树分别存某种颜色,  对于某个颜色的某个位置,  要么是, 要么不是, 超时了,  用二进制每一位表示每个颜色, 1表示有, 0表示没有这个颜色, 合并就是或操作了. 查询就是查1的个数了.

      1 //#define txtout
      2 //#define debug
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<stack>
     13 #include<queue>
     14 #include<set>
     15 #include<map>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double pi=acos(-1.0);
     20 const double eps=1e-8;
     21 const int inf=0x3f3f3f3f;
     22 const int M=1e5+10;
     23 class SegmentTree{
     24     #define lrrt int L,int R,int rt
     25     #define iall 1,n,1
     26     #define imid int mid=(L+R)>>1
     27     #define lson L,mid,rt<<1
     28     #define rson mid+1,R,rt<<1|1
     29     static const int MV=1e5+10;
     30     struct T{
     31         int value;
     32         int cover;
     33     }tree[MV<<2];
     34     int n;
     35     void pushup(int rt){
     36         tree[rt].value=tree[rt<<1].value|tree[rt<<1|1].value;
     37     }
     38     void build(lrrt){
     39         tree[rt].cover=-1;
     40         tree[rt].value=1;
     41         if(L==R) return ;
     42         imid;
     43         build(lson);
     44         build(rson);
     45     }
     46     void pushdown(int rt){
     47         if(tree[rt].cover!=-1){
     48             tree[rt<<1].cover=tree[rt].cover;
     49             tree[rt<<1|1].cover=tree[rt].cover;
     50             tree[rt<<1].value=tree[rt].cover;
     51             tree[rt<<1|1].value=tree[rt].cover;
     52             tree[rt].cover=-1;
     53         }
     54     }
     55     void update(int x,int y,int z,lrrt){
     56         if(x<=L&&R<=y){
     57             tree[rt].cover=1<<(z-1);
     58             tree[rt].value=1<<(z-1);
     59             return ;
     60         }
     61         imid;
     62         pushdown(rt);
     63         if(mid>=x) update(x,y,z,lson);
     64         if(mid<y)  update(x,y,z,rson);
     65         pushup(rt);
     66     }
     67     int query(int x,int y,lrrt){
     68         if(x<=L&&R<=y) return tree[rt].value;
     69         imid;
     70         pushdown(rt);
     71         int result=0;
     72         if(mid>=x) result|=query(x,y,lson);
     73         if(mid<y)  result|=query(x,y,rson);
     74         return result;
     75     }
     76 public:
     77     void init(int tn){
     78         n=tn;
     79         build(iall);
     80     }
     81     int query(int x,int y){
     82         return query(x,y,iall);
     83     }
     84     void update(int x,int y,int z){
     85         update(x,y,z,iall);
     86     }
     87 }st;
     88 int n,t,m;
     89 struct Q{
     90     int x,y,z;
     91     char type[4];
     92 }q[M];
     93 vector<int> answer;
     94 void solve(){
     95     st.init(n);
     96     answer.clear();
     97     for(int i=0;i<m;i++){
     98         if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
     99         if(q[i].type[0]=='C'){
    100             st.update(q[i].x,q[i].y,q[i].z);
    101             continue;
    102         }
    103         int sum=0;
    104         int result=st.query(q[i].x,q[i].y);
    105         for(int j=0;j<t;j++){
    106             if((result>>j)&1) sum++;
    107         }
    108         answer.push_back(sum);
    109     }
    110 }
    111 int main() {
    112 #ifdef txtout
    113     freopen("in.txt","r",stdin);
    114     freopen("out.txt","w",stdout);
    115 #endif // txtout
    116     while(~scanf("%d%d%d",&n,&t,&m)) {
    117         for(int i=0; i<m; i++) {
    118             scanf("%s%d%d",q[i].type,&q[i].x,&q[i].y);
    119             if(q[i].type[0]=='C'){
    120                 scanf("%d",&q[i].z);
    121             }
    122         }
    123         solve();
    124         for(int i=0; i<answer.size(); i++) {
    125             printf("%d
    ",answer[i]);
    126         }
    127     }
    128     return 0;
    129 }
    View Code

    13年写的, 是如果一个区间都是一个颜色, 就是这个颜色, 否则为0,  查询时 遇到一个区间是同一种颜色的 ,直接返回, 否则暴力搜 . 颜色比较少, 可能样例水吧 这么做也能过, 复杂度不好估计.

     1 #include<cstdio>
     2 #define lson L,mid,rt<<1
     3 #define rson mid+1,R,rt<<1|1
     4 const int M=100010;
     5 int tree[M<<2],lazy[M<<2];
     6 bool v[64];
     7 void pushup(int rt){
     8     if(tree[rt<<1]==tree[rt<<1|1]){
     9         tree[rt]=tree[rt<<1];
    10     }
    11     else{
    12         tree[rt]=0;
    13     }
    14 }
    15 void build(int L,int R,int rt){
    16     lazy[rt]=0;
    17     tree[rt]=1;
    18     if(L==R){
    19         return ;
    20     }
    21     int mid=(L+R)>>1;
    22     build(lson);
    23     build(rson);
    24 }
    25 void pushdown(int rt){
    26     if(lazy[rt]){
    27         lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
    28         tree[rt]=tree[rt<<1]=tree[rt<<1|1]=lazy[rt];
    29         lazy[rt]=0;
    30     }
    31 }
    32 void update(int x,int y,int z,int L,int R,int rt){
    33     if(x<=L&&R<=y){
    34         lazy[rt]=z;
    35         tree[rt]=z;
    36         return ;
    37     }
    38     int mid=(L+R)>>1;
    39     pushdown(rt);
    40     if(mid>=x)
    41         update(x,y,z,lson);
    42     if(mid<y)
    43         update(x,y,z,rson);
    44     pushup(rt);
    45 }
    46 void query(int x,int y,int L,int R,int rt){
    47     if(x<=L&&R<=y){
    48         if(tree[rt]){
    49             v[tree[rt]]=true;
    50             return ;
    51         }
    52     }
    53     int mid=(L+R)>>1;
    54     pushdown(rt);
    55     if(mid>=x)
    56         query(x,y,lson);
    57     if(mid<y)
    58         query(x,y,rson);
    59 }
    60 int main(){
    61     int n,t,m;
    62     while(~scanf("%d%d%d",&n,&t,&m)){
    63         build(1,n,1);
    64         while(m--){
    65             int a,b,c;
    66             char s[4];
    67             scanf("%s%d%d",s,&a,&b);
    68             if(a>b){
    69                 int temp=a;
    70                 a=b;
    71                 b=temp;
    72             }
    73             if(s[0]=='C'){
    74                 scanf("%d",&c);
    75                 update(a,b,c,1,n,1);
    76             }
    77             else{
    78                 for(int i=1;i<=t;i++){
    79                     v[i]=false;
    80                 }
    81                 int ans=0;
    82                 query(a,b,1,n,1);
    83                 for(int i=1;i<=t;i++){
    84                     if(v[i]){
    85                         ans++;
    86                     }
    87                 }
    88                 printf("%d
    ",ans);
    89             }
    90         }
    91     }
    92     return 0;
    93 }
    View Code

    poj 2886

    poj 3225

    poj 1436,zoj 1391, uva 2441

    poj 2991

    poj 1308, zoj 1268 ,uva 615

    uva 117

    uva 10735

    uva 10054 uva 2036

    uva 10818

    uva 10937

  • 相关阅读:
    [转]用异或交换两个整数的陷阱
    线索化二叉树
    [转]Socket编程中,阻塞与非阻塞的区别
    两个链表的归并
    [转] std::string and stl 算法
    类图
    leetcode 答案
    about raw socket
    54. Spiral Matrix【数组】
    矩阵乘法问题的实现
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/5774122.html
Copyright © 2020-2023  润新知