• 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
    ",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
    ",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
    ",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
    ",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
    ",nl,nr);
    151         if(opt[i]^2) IT.modify_set(nl,nr,0);
    152         else IT.modify_set(nl,nr,1);
    153         printf("%d
    ",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 */    
    然后是离散化+线段树
  • 相关阅读:
    最短Hamilton路径-状压dp解法
    泡芙
    斗地主
    楼间跳跃
    联合权值
    虫食算
    抢掠计划
    间谍网络
    城堡the castle
    【模板】缩点
  • 原文地址:https://www.cnblogs.com/xuzihanllaa/p/8299148.html
Copyright © 2020-2023  润新知