Codeforces 915E Physical Education Lessons

原题传送门

我承认,比赛的时候在C题上卡了好久(最后也不会),15min水掉D后(最后还FST了。。),看到E时已经只剩15min了。尽管一眼看出是离散化+线段树的裸题,但是没有时间写,实在尴尬。

赛后先照习惯码出线段树,提交上去WA4???看了好久没看出问题,怎么调都不对。这时TJW忽悠我:“我写的可持久化线段树啊,不用离散化了啊。”我信了,码出主席树(实话说确实不用想那么多了,无脑动态开点就行了),提交上去TLE18???回头一问TJW:“我FST了啊。”我:(

不过TJW还是提供了一个非常有用的信息:像这道题的离散化线段树,可以将区间左端点与(区间右端点+1)进行离散化,然后线段树写左闭右开的(碰巧我就是这么写的),这样避免了很多麻烦。我原本的处理方法是将左右端点以及它们的下一位都塞进去离散化,虽然也没有问题,但是空间翻了倍。

回头重新调线段树,结果秒发现问题:我在main函数中调用线段树时参数用的是离散化的下标,结果线段树里我又把下标转回了未离散化的下标:(,实在是画蛇添足。。

 

  1 /*    Codeforces 915E Physical Education Lessons
  2     1st Edition:2018.1.15 Monday
  3     Algorithm:HJT Tree
  4 */
  5 #include <iostream>
  6 #include <cstdio>
  7 #include <algorithm>
  8 #include <cmath>
  9 #include <cstring>
 10 #include <vector>
 11 #include <map>
 12 #include <set>
 13 #include <bitset>
 14 #include <queue>
 15 #include <deque>
 16 #include <stack>
 17 #include <iomanip>
 18 #include <cstdlib>
 19 #include <ctime>
 20 #include <cctype>
 21 using namespace std;
 22 
 23 #define is_lower(c) (c>='a' && c<='z')
 24 #define is_upper(c) (c>='A' && c<='Z')
 25 #define is_alpha(c) (is_lower(c) || is_upper(c))
 26 #define is_digit(c) (c>='0' && c<='9')
 27 #define stop system("PAUSE")
 28 #define ForG(a,b,c) for(int (a)=c.head[b];(a);(a)=c.E[a].nxt)
 29 #define For(a,b,c) for(int (a)=(b);(a)<=(c);++a)
 30 #define min(a,b) ((a)<(b)?(a):(b))
 31 #define max(a,b) ((a)>(b)?(a):(b))
 32 #define shl(x,y) ((x)<<(y))
 33 #define shr(x,y) ((x)>>(y))
 34 #define mp make_pair
 35 #define pb push_back
 36 #ifdef ONLINE_JUDGE
 37 #define hash rename_hash
 38 #define next rename_next
 39 #define prev rename_prev
 40 #endif
 41 typedef long long ll;
 42 typedef unsigned long long ull;
 43 typedef pair<int,int> pii;
 44 typedef pair<ll,ll> pll;
 45 typedef vector<int> vi;
 46 typedef double db;
 47 const ll inf=2000000007LL;
 48 const double EPS=1e-10;
 49 const ll inf_ll=(ll)1e18;
 50 const ll maxn=300005LL;
 51 const ll mod=1000000007LL;
 52 
 53 int n,q;
 54 
 55 struct HJT_Tree{
 56     struct node{
 57         int ch[2],l,r;
 58         int set,sum;
 59         node():l(0),r(0),set(-1),sum(0){ch[0]=ch[1]=0;}
 60         node(int nl,int nr):l(nl),r(nr),set(-1),sum(0){ch[0]=ch[1]=0;}
 61     }T[maxn<<5];
 62     int size,root;
 63     #define lch(u) T[u].ch[0]
 64     #define rch(u) T[u].ch[1]
 65     
 66     inline print_node(int u){printf("[%d] %d %d %d %d\n",u,T[u].l,T[u].r,T[u].set,T[u].sum);}
 67     inline int new_node(int l,int r){
 68         T[++size]=node(l,r);
 69         return size;
 70     }
 71     inline void set_node(int u,int val){
 72         T[u].set=val;
 73         T[u].sum=(T[u].r-T[u].l)*val;
 74     }
 75     inline void init(){
 76         root=1;
 77         For(i,0,size) T[i]=node();
 78         T[1]=node(1,n+1);
 79         size=1;
 80     }
 81     inline void push_up(int u){
 82         T[u].sum=T[lch(u)].sum+T[rch(u)].sum;
 83     }
 84     inline void append(int u){
 85         int nl=T[u].l,nr=T[u].r,mid=(nl+nr)>>1;
 86         if(!lch(u)) lch(u)=new_node(nl,mid);
 87         if(!rch(u)) rch(u)=new_node(mid,nr);
 88     }
 89     inline void push_down(int u){
 90         append(u);
 91         if(T[u].set>=0){
 92             set_node(lch(u),T[u].set);set_node(rch(u),T[u].set);
 93             T[u].set=-1;
 94         }
 95     }
 96     void _modify(int &u,int nl,int nr,int l,int r,int val){
 97         if(nl>=r || nr<=l) return;
 98 //        print_node(u);
 99         if(nl>=l && nr<=r){set_node(u,val);return;}
100         push_down(u);
101         int mid=(nl+nr)>>1;
102         _modify(lch(u),nl,mid,l,r,val);_modify(rch(u),mid,nr,l,r,val);
103         push_up(u);
104     }
105     inline void modify(int l,int r,int val){_modify(root,1,n+1,l,r+1,val);}
106     int _query(int &u,int nl,int nr,int l,int r){
107         if(nl>=r || nr<=l) return 0;
108         if(nl>=l && nr<=r) return T[u].sum;
109         push_down(u);
110         int mid=(nl+nr)>>1;
111         return _query(lch(u),nl,mid,l,r)+_query(rch(u),mid,nr,l,r);
112     }
113     inline int query(int l,int r){return _query(root,1,n+1,l,r+1);}
114     #undef lch
115     #undef rch
116 }HJT;
117 
118 int main(){
119     scanf("%d%d",&n,&q);
120     HJT.init();
121     HJT.modify(1,n,1);
122     while(q--){
123         int x,y,opt;
124         scanf("%d%d%d",&x,&y,&opt);
125         if(opt^2) HJT.modify(x,y,0);
126         else HJT.modify(x,y,1);
127         printf("%d\n",HJT.query(1,n+1));
128     }
129     return 0;
130 }
131 
132 /*
133 4
134 6
135 1 2 1
136 3 4 1
137 2 3 2
138 1 3 2
139 2 4 1
140 1 4 2
141 
142 */
先贴上主席树的代码
  1 /*    Codeforces 915E Physical Education Lessons
  2     1st Edition:2018.1.14 Sunday
  3     2nd Edition:2018.1.16 Tuesday
  4     Algorithm:Interval Tree,Hash
  5 */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <algorithm>
  9 #include <cmath>
 10 #include <cstring>
 11 #include <vector>
 12 #include <map>
 13 #include <set>
 14 #include <bitset>
 15 #include <queue>
 16 #include <deque>
 17 #include <stack>
 18 #include <iomanip>
 19 #include <cstdlib>
 20 #include <ctime>
 21 #include <cctype>
 22 using namespace std;
 23 
 24 #define is_lower(c) (c>='a' && c<='z')
 25 #define is_upper(c) (c>='A' && c<='Z')
 26 #define is_alpha(c) (is_lower(c) || is_upper(c))
 27 #define is_digit(c) (c>='0' && c<='9')
 28 #define stop system("PAUSE")
 29 #define ForG(a,b,c) for(int (a)=c.head[b];(a);(a)=c.E[a].nxt)
 30 #define For(a,b,c) for(int (a)=(b);(a)<=(c);++a)
 31 #define min(a,b) ((a)<(b)?(a):(b))
 32 #define max(a,b) ((a)>(b)?(a):(b))
 33 #define shl(x,y) ((x)<<(y))
 34 #define shr(x,y) ((x)>>(y))
 35 #define mp make_pair
 36 #define pb push_back
 37 #ifdef ONLINE_JUDGE
 38 #define hash rename_hash
 39 #define next rename_next
 40 #define prev rename_prev
 41 #endif
 42 typedef long long ll;
 43 typedef unsigned long long ull;
 44 typedef pair<int,int> pii;
 45 typedef pair<ll,ll> pll;
 46 typedef vector<int> vi;
 47 typedef double db;
 48 const ll inf=2000000007LL;
 49 const double EPS=1e-10;
 50 const ll inf_ll=(ll)1e18;
 51 const ll maxn=300005LL;
 52 const ll mod=1000000007LL;
 53 
 54 int n,q;
 55 int l[maxn],r[maxn],opt[maxn];
 56 vi Hash;
 57 
 58 struct Interval_Tree{
 59     struct node{
 60         int l,r,sum,set,size;
 61         node(){}
 62         node(int nl,int nr):l(nl),r(nr),set(-1),size(0),sum(0){}
 63     }T[maxn<<3];
 64     #define lch(u) (u<<1)
 65     #define rch(u) (u<<1|1)
 66     
 67     inline void push_up(int u){
 68         T[u].sum=T[lch(u)].sum+T[rch(u)].sum;
 69     }
 70     inline void set_node(int u,int val){
 71         T[u].set=val;
 72         T[u].sum=val*T[u].size;
 73     }
 74     inline void push_down(int u){
 75         if(T[u].set>=0){
 76             set_node(lch(u),T[u].set);set_node(rch(u),T[u].set);
 77             T[u].set=-1;
 78         }
 79     }
 80     void _build(int u,int l,int r){
 81         T[u]=node(l,r);
 82         if(l==r-1){
 83             T[u].size=Hash[r]-Hash[l];
 84             set_node(u,1);
 85             return;
 86         }
 87         _build(lch(u),l,(l+r)>>1);_build(rch(u),(l+r)>>1,r);
 88         push_up(u);
 89         T[u].size=T[lch(u)].size+T[rch(u)].size;
 90     }
 91     inline void build(int size){
 92         _build(1,1,size);
 93     }
 94     void _modify_set(int u,int l,int r,int val){
 95         int nl=T[u].l,nr=T[u].r;
 96         if(nl>=l && nr<=r){set_node(u,val);return;}
 97         if(nl>=r || nr<=l) return;
 98         push_down(u);
 99         _modify_set(lch(u),l,r,val);_modify_set(rch(u),l,r,val);
100         push_up(u);
101     }
102     inline void modify_set(int l,int r,int val){
103         _modify_set(1,l,r,val);        //这里本来写的是_modify_set(1,Hash[l],Hash[r],val);
104     }
105     int _query_sum(int u,int l,int r){
106         int nl=T[u].l,nr=T[u].r;
107         if(nl>=l && nr<=r) return T[u].sum;
108         if(nl>=r || nr<=l) return 0;
109         push_down(u);
110         return _query_sum(lch(u),l,r)+_query_sum(rch(u),l,r);
111     }
112     inline int query_sum(int l,int r){
113         return _query_sum(1,l,r);    //这里同理。。
114     }
115     inline void print_node(int u){
116         printf("[%d] %d %d %d %d %d\n",u,T[u].l,T[u].r,T[u].size,T[u].sum,T[u].set);
117     }
118     void _print(int u){
119         int nl=T[u].l,nr=T[u].r;
120         print_node(u);
121         if(nl==nr-1) return;
122         _print(lch(u));_print(rch(u));
123     }
124     inline void print(){_print(1);}
125     #undef lch
126     #undef rch
127 }IT;
128 
129 int main(){
130     scanf("%d%d",&n,&q);
131     Hash.pb(1);Hash.pb(0);Hash.pb(n+1);
132     For(i,1,q){
133         scanf("%d%d%d",l+i,r+i,opt+i);
134         Hash.pb(l[i]);Hash.pb(r[i]+1);
135     }
136     sort(Hash.begin(),Hash.end());
137     Hash.erase(unique(Hash.begin(),Hash.end()),Hash.end());
138     int hash_size=(int)Hash.size();
139 /*
140     For(i,1,hash_size-1) printf("%d ",Hash[i]);
141     puts("");
142 */
143     IT.build(hash_size-1);
144 //    printf("%d\n",IT.query_sum(1,hash_size-1));
145     For(i,1,q){
146 //        IT.print();
147         int nl=l[i],nr=r[i];
148         nl=lower_bound(Hash.begin(),Hash.end(),nl)-Hash.begin();
149         nr=lower_bound(Hash.begin(),Hash.end(),nr+1)-Hash.begin();
150 //        printf("%d %d\n",nl,nr);
151         if(opt[i]^2) IT.modify_set(nl,nr,0);
152         else IT.modify_set(nl,nr,1);
153         printf("%d\n",IT.query_sum(1,hash_size-1));
154     }
155     return 0;
156 }
157 
158 /*
159 4
160 6
161 1 2 1
162 3 4 1
163 2 3 2
164 1 3 2
165 2 4 1
166 1 4 2
167 
168 7
169 10
170 5 7 1
171 5 6 2
172 7 7 2
173 6 7 2
174 5 5 1
175 3 6 2
176 1 3 2
177 5 6 1
178 1 3 1
179 6 7 1
180 
181 */    
然后是离散化+线段树

 

posted @ 2018-01-16 22:24  xuzihanllaa  阅读(458)  评论(0编辑  收藏  举报