第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\n",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\n",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\n",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\n",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\n",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\n",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

转载于:https://www.cnblogs.com/gaolzzxin/p/5774122.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值