原题传送门

我承认,比赛的时候在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. json的那些事

    1.什么是json? json(javascript object notation)全称是javascript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据.简单来说 ...

  2. Spark术语

    1.resilient distributed dataset (RDD) The core programming abstraction in Spark, consisting of a fau ...

  3. Laravel学习笔记(二)

    解决了类自动加载的问题,剩下的问题就是看文档了,laravel的官方文档虽然简单,但是却包含了很多基础知识,学习Laravel最好先看看官方文档,我感觉帮助很大,因为laravel框架的源码看起来并不 ...

  4. 接口json数据与数据库数据循环比对校验

    创建测试计划,加载数据库驱动: 线程组: csv配置元件: 注:Filename用的是相对路径,csv文件要与jmeter脚本文件在同一目录 JDBC连接配置: jdbc请求: 用户定义的变量: ht ...

  5. 将Maven的Web项目部署到windows的Tomcat里

    这里我用的是win7和tomcat8,且tomcat8下载的是压缩包而非安装文件. 第一步:先将tomcat8安装服务,cmd里更改目录为tomcat8(即压缩包解压后的那个文件夹)的bin文件夹, ...

  6. SVO环境搭建

    我是装了双系统,实验OS:Ubuntu14.04 Installation: Plain CMake (No ROS) 首先,建立一个工作目录比如:workspace,然后把下面的需要的都在该目录下进 ...

  7. bzoj 4446: [Scoi2015]小凸玩密室

    Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...

  8. bzoj 3142: [Hnoi2013]数列

    Description 小T最近在学着买股票,他得到内部消息:F公司的股票将会疯涨.股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为N.在疯涨的K天中小T观察到:除第一天外每天的股价都比前 ...

  9. java方式连接数据操作数据库

    package com.bdqn.dao.impl; import java.io.IOException;import java.io.InputStream;import java.io.Seri ...

  10. linux下搜索指定内容

    echo " ls *.$2 | while read file;do out=$( (grep -n $1 $file) ) [ -n \"$out\" ] & ...