原题传送门

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

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

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

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

 /*    Codeforces 915E Physical Education Lessons
1st Edition:2018.1.15 Monday
Algorithm:HJT Tree
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cctype>
using namespace std; #define is_lower(c) (c>='a' && c<='z')
#define is_upper(c) (c>='A' && c<='Z')
#define is_alpha(c) (is_lower(c) || is_upper(c))
#define is_digit(c) (c>='0' && c<='9')
#define stop system("PAUSE")
#define ForG(a,b,c) for(int (a)=c.head[b];(a);(a)=c.E[a].nxt)
#define For(a,b,c) for(int (a)=(b);(a)<=(c);++a)
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define shl(x,y) ((x)<<(y))
#define shr(x,y) ((x)>>(y))
#define mp make_pair
#define pb push_back
#ifdef ONLINE_JUDGE
#define hash rename_hash
#define next rename_next
#define prev rename_prev
#endif
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef double db;
const ll inf=2000000007LL;
const double EPS=1e-;
const ll inf_ll=(ll)1e18;
const ll maxn=300005LL;
const ll mod=1000000007LL; int n,q; struct HJT_Tree{
struct node{
int ch[],l,r;
int set,sum;
node():l(),r(),set(-),sum(){ch[]=ch[]=;}
node(int nl,int nr):l(nl),r(nr),set(-),sum(){ch[]=ch[]=;}
}T[maxn<<];
int size,root;
#define lch(u) T[u].ch[0]
#define rch(u) T[u].ch[1] 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);}
inline int new_node(int l,int r){
T[++size]=node(l,r);
return size;
}
inline void set_node(int u,int val){
T[u].set=val;
T[u].sum=(T[u].r-T[u].l)*val;
}
inline void init(){
root=;
For(i,,size) T[i]=node();
T[]=node(,n+);
size=;
}
inline void push_up(int u){
T[u].sum=T[lch(u)].sum+T[rch(u)].sum;
}
inline void append(int u){
int nl=T[u].l,nr=T[u].r,mid=(nl+nr)>>;
if(!lch(u)) lch(u)=new_node(nl,mid);
if(!rch(u)) rch(u)=new_node(mid,nr);
}
inline void push_down(int u){
append(u);
if(T[u].set>=){
set_node(lch(u),T[u].set);set_node(rch(u),T[u].set);
T[u].set=-;
}
}
void _modify(int &u,int nl,int nr,int l,int r,int val){
if(nl>=r || nr<=l) return;
// print_node(u);
if(nl>=l && nr<=r){set_node(u,val);return;}
push_down(u);
int mid=(nl+nr)>>;
_modify(lch(u),nl,mid,l,r,val);_modify(rch(u),mid,nr,l,r,val);
push_up(u);
}
inline void modify(int l,int r,int val){_modify(root,,n+,l,r+,val);}
int _query(int &u,int nl,int nr,int l,int r){
if(nl>=r || nr<=l) return ;
if(nl>=l && nr<=r) return T[u].sum;
push_down(u);
int mid=(nl+nr)>>;
return _query(lch(u),nl,mid,l,r)+_query(rch(u),mid,nr,l,r);
}
inline int query(int l,int r){return _query(root,,n+,l,r+);}
#undef lch
#undef rch
}HJT; int main(){
scanf("%d%d",&n,&q);
HJT.init();
HJT.modify(,n,);
while(q--){
int x,y,opt;
scanf("%d%d%d",&x,&y,&opt);
if(opt^) HJT.modify(x,y,);
else HJT.modify(x,y,);
printf("%d\n",HJT.query(,n+));
}
return ;
} /*
4
6
1 2 1
3 4 1
2 3 2
1 3 2
2 4 1
1 4 2 */

先贴上主席树的代码

 /*    Codeforces 915E Physical Education Lessons
1st Edition:2018.1.14 Sunday
2nd Edition:2018.1.16 Tuesday
Algorithm:Interval Tree,Hash
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cctype>
using namespace std; #define is_lower(c) (c>='a' && c<='z')
#define is_upper(c) (c>='A' && c<='Z')
#define is_alpha(c) (is_lower(c) || is_upper(c))
#define is_digit(c) (c>='0' && c<='9')
#define stop system("PAUSE")
#define ForG(a,b,c) for(int (a)=c.head[b];(a);(a)=c.E[a].nxt)
#define For(a,b,c) for(int (a)=(b);(a)<=(c);++a)
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define shl(x,y) ((x)<<(y))
#define shr(x,y) ((x)>>(y))
#define mp make_pair
#define pb push_back
#ifdef ONLINE_JUDGE
#define hash rename_hash
#define next rename_next
#define prev rename_prev
#endif
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef double db;
const ll inf=2000000007LL;
const double EPS=1e-;
const ll inf_ll=(ll)1e18;
const ll maxn=300005LL;
const ll mod=1000000007LL; int n,q;
int l[maxn],r[maxn],opt[maxn];
vi Hash; struct Interval_Tree{
struct node{
int l,r,sum,set,size;
node(){}
node(int nl,int nr):l(nl),r(nr),set(-),size(),sum(){}
}T[maxn<<];
#define lch(u) (u<<1)
#define rch(u) (u<<1|1) inline void push_up(int u){
T[u].sum=T[lch(u)].sum+T[rch(u)].sum;
}
inline void set_node(int u,int val){
T[u].set=val;
T[u].sum=val*T[u].size;
}
inline void push_down(int u){
if(T[u].set>=){
set_node(lch(u),T[u].set);set_node(rch(u),T[u].set);
T[u].set=-;
}
}
void _build(int u,int l,int r){
T[u]=node(l,r);
if(l==r-){
T[u].size=Hash[r]-Hash[l];
set_node(u,);
return;
}
_build(lch(u),l,(l+r)>>);_build(rch(u),(l+r)>>,r);
push_up(u);
T[u].size=T[lch(u)].size+T[rch(u)].size;
}
inline void build(int size){
_build(,,size);
}
void _modify_set(int u,int l,int r,int val){
int nl=T[u].l,nr=T[u].r;
if(nl>=l && nr<=r){set_node(u,val);return;}
if(nl>=r || nr<=l) return;
push_down(u);
_modify_set(lch(u),l,r,val);_modify_set(rch(u),l,r,val);
push_up(u);
}
inline void modify_set(int l,int r,int val){
_modify_set(,l,r,val); //这里本来写的是_modify_set(1,Hash[l],Hash[r],val);
}
int _query_sum(int u,int l,int r){
int nl=T[u].l,nr=T[u].r;
if(nl>=l && nr<=r) return T[u].sum;
if(nl>=r || nr<=l) return ;
push_down(u);
return _query_sum(lch(u),l,r)+_query_sum(rch(u),l,r);
}
inline int query_sum(int l,int r){
return _query_sum(,l,r); //这里同理。。
}
inline void print_node(int u){
printf("[%d] %d %d %d %d %d\n",u,T[u].l,T[u].r,T[u].size,T[u].sum,T[u].set);
}
void _print(int u){
int nl=T[u].l,nr=T[u].r;
print_node(u);
if(nl==nr-) return;
_print(lch(u));_print(rch(u));
}
inline void print(){_print();}
#undef lch
#undef rch
}IT; int main(){
scanf("%d%d",&n,&q);
Hash.pb();Hash.pb();Hash.pb(n+);
For(i,,q){
scanf("%d%d%d",l+i,r+i,opt+i);
Hash.pb(l[i]);Hash.pb(r[i]+);
}
sort(Hash.begin(),Hash.end());
Hash.erase(unique(Hash.begin(),Hash.end()),Hash.end());
int hash_size=(int)Hash.size();
/*
For(i,1,hash_size-1) printf("%d ",Hash[i]);
puts("");
*/
IT.build(hash_size-);
// printf("%d\n",IT.query_sum(1,hash_size-1));
For(i,,q){
// IT.print();
int nl=l[i],nr=r[i];
nl=lower_bound(Hash.begin(),Hash.end(),nl)-Hash.begin();
nr=lower_bound(Hash.begin(),Hash.end(),nr+)-Hash.begin();
// printf("%d %d\n",nl,nr);
if(opt[i]^) IT.modify_set(nl,nr,);
else IT.modify_set(nl,nr,);
printf("%d\n",IT.query_sum(,hash_size-));
}
return ;
} /*
4
6
1 2 1
3 4 1
2 3 2
1 3 2
2 4 1
1 4 2 7
10
5 7 1
5 6 2
7 7 2
6 7 2
5 5 1
3 6 2
1 3 2
5 6 1
1 3 1
6 7 1 */

然后是离散化+线段树

Codeforces 915E Physical Education Lessons的更多相关文章

  1. Codeforces 915E. Physical Education Lessons(动态开点线段树)

    E. Physical Education Lessons 题目:一段长度为n的区间初始全为1,每次成段赋值0或1,求每次操作后的区间总和.(n<=1e9,q<=3e5) 题意:用线段树做 ...

  2. codeforces 915E - Physical Education Lessons 动态开点线段树

    题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...

  3. codeforces 893F - Physical Education Lessons 动态开点线段树合并

    https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...

  4. Physical Education Lessons CodeForces - 915E (动态开点线段树)

    Physical Education Lessons CodeForces - 915E This year Alex has finished school, and now he is a fir ...

  5. Codeforces 915 E Physical Education Lessons

    题目描述 This year Alex has finished school, and now he is a first-year student of Berland State Univers ...

  6. 【CodeForces】915 E. Physical Education Lessons 线段树

    [题目]E. Physical Education Lessons [题意]10^9范围的区间覆盖,至多3*10^5次区间询问. [算法]线段树 [题解]每次询问至多增加两段区间,提前括号分段后线段树 ...

  7. CF915E Physical Education Lessons 动态开点线段树

    题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...

  8. 【题解】Luogu CF915E Physical Education Lessons

    原题传送门:CF915E Physical Education Lessons 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 这道题很简单啊 每个操作就是区间赋值,顺带把总和修 ...

  9. CF915E Physical Education Lessons

    题意: Alex高中毕业了,他现在是大学新生.虽然他学习编程,但他还是要上体育课,这对他来说完全是一个意外.快要期末了,但是不幸的Alex的体育学分还是零蛋! Alex可不希望被开除,他想知道到期末还 ...

随机推荐

  1. git 设置和取消代理

    # 设置ss git config --global http.proxy 'socks5://127.0.0.1:1080' git config --global https.proxy 'soc ...

  2. 《TCP-IP详解卷3:TCP 事务协议、HTTP、NNTP和UNIX域协议》【PDF】下载

    TCP-IP详解卷3:TCP 事务协议.HTTP.NNTP和UNIX域协议>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062539 ...

  3. 转:一篇讲线上优化查 CPU的脚本

    原文链接:https://my.oschina.net/leejun2005/blog/1524687   摘要: 本文主要针对 Java 服务而言 0.背景 经常做后端服务开发的同学,或多或少都遇到 ...

  4. seo我告诉你

    seo我告诉你,这回seo真的告诉你百度云链接 链接:http://pan.baidu.com/s/1qYpM9y8 密码:mad6 seo优化教程:

  5. iView的使用【CDN向】

    直接粗暴地上html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  6. JS画几何图形之二【圆】

    半径为r的圆上的点p(x,y)与圆心O(x0,y0)的关系: x = x0+rcosA;  y = y0+rsinA ,A为弧度 样例:http://www.zhaojz.com.cn/demo/dr ...

  7. 在html中使用js

    1.使用defer属性可以让脚本在文档完全呈现出来之后在执行,延迟脚本总是按照制定他们的顺序进行. 2.使用async属性可以表示当前脚本不必等待其他脚本,也不必阻塞文档呈现,不能保证异步顺序按照它们 ...

  8. Java NIO (一) 初识NIO

    Java NIO(New IO / Non-Blocking IO)是从JDK 1.4版本开始引入的IO API , 可以替代标准的Java IO API .NIO与原来标准IO有同样的作用和目的,但 ...

  9. Oracle 启动参数

    查看数据库的SID DB_NAME SERVICE_NAME

  10. Macaca自动化工具之uirecorder脚本录制

    UI Recorder功能介绍 支持所有用户行为: 键盘事件, 鼠标事件, alert, 文件上传, 拖放, svg, shadow dom 支持无线native app录制, 基于macaca实现: ...