九度OJ 题目1496:数列区间 (线段树 区间合并 +成段更新)
来源:互联网 发布:董宇阳,知乎 编辑:程序博客网 时间:2024/05/01 02:37
题目链接
线段树 区间合并 成段更新题,什么鬼,模拟它,不断地成段更新,最后好不容易调试出来了,发现TLE,而且只超了80ms,什么鬼!!!
然后小小地优化了一下,如果前面的一些区间被最后的一个区间完全覆盖的话,就没必要更新它。小小的优化了一下,就过了,是飘过。。。。
前前后后搞了3个小时吧。
#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>using namespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 1000005;int lsum[maxn<<2] , rsum[maxn<<2] , msum[maxn<<2],ln[maxn<<2],rn[maxn<<2];int cover[maxn<<2];int x[maxn],y[maxn],ansx[maxn],ansy[maxn];int cnt=0;struct node{ int x,y;}a[100005],ans[100005];void PushDown(int rt,int m){ if (cover[rt] != -1) { cover[rt<<1] = cover[rt<<1|1] = cover[rt]; ln[rt<<1]=rn[rt<<1]=cover[rt]; ln[rt<<1|1]=rn[rt<<1|1]=cover[rt]; msum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] =m - (m >> 1); msum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = (m >> 1); //printf("%d: rt lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,lsum[rt],rsum[rt],msum[rt],ln[rt],rn[rt],cover[rt]); //printf("%d: lson lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,lsum[rt<<1],rsum[rt<<1],msum[rt<<1],ln[rt<<1],rn[rt<<1],cover[rt<<1]); // printf("%d: rson lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,lsum[rt<<1|1],rsum[rt<<1|1],msum[rt<<1|1],ln[rt<<1|1],rn[rt<<1|1],cover[rt<<1|1]); cover[rt] = -1; }}void PushUp(int rt,int m){ lsum[rt] = lsum[rt<<1];rsum[rt] = rsum[rt<<1|1]; msum[rt] = max(msum[rt<<1],msum[rt<<1|1]); ln[rt]=ln[rt<<1];rn[rt]=rn[rt<<1|1]; if(rn[rt<<1]==ln[rt<<1|1]&&rn[rt<<1]&&ln[rt<<1|1]) { if (lsum[rt] == m - (m >> 1)) lsum[rt] += lsum[rt<<1|1]; if (rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt<<1]; msum[rt] = max(lsum[rt<<1|1] + rsum[rt<<1] , msum[rt]); }}void build(int l,int r,int rt){ msum[rt] = lsum[rt] = rsum[rt] = 0;//r - l + 1; ln[rt]=rn[rt]=0; cover[rt] = -1; if (l == r) return ; int m = (l + r) >> 1; build(lson); build(rson);}void update(int L,int R,int c,int l,int r,int rt){ if (L <= l && r <= R) { msum[rt] = lsum[rt] = rsum[rt] = r - l + 1; cover[rt] = c; ln[rt]=rn[rt]=c; //printf("%d: [%d %d] lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,l,r,lsum[rt],rsum[rt],msum[rt],ln[rt],rn[rt],cover[rt]); return ; } PushDown(rt , r - l + 1); int m = (l + r) >> 1; if (L <= m) update(L , R , c , lson); if (m < R) update(L , R , c , rson); PushUp(rt , r - l + 1); //printf("%d: [%d %d] lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,l,r,lsum[rt],rsum[rt],msum[rt],ln[rt],rn[rt],cover[rt]);}int Scan(){int res = 0, ch, flag = 0;if((ch = getchar()) == '-')//判断正负flag = 1;else if(ch >= '0' && ch <= '9')//得到完整的数res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}int main(){ int n , m; //freopen("in.txt","r",stdin); //while(n=Scan()) while(~scanf("%d%d",&n,&m)) { //m=Scan(); build(1 , n , 1); for(int i=1;i<=m;i++) scanf("%d%d",&a[i].x,&a[i].y); int p=1,l=a[m].x,r=a[m].y; if(m) ans[p++]=a[m]; for(int i=m;i>=1;i--) if(a[i].x<=l||a[i].y>=r) ans[p++]=a[i]; for(int i=p-1,id=1;i>=1;i--) { //printf("update[%d,%d]\n",ans[i].x,ans[i].y); update(ans[i].x,ans[i].y,id++,1,n,1); } //puts("yes"); printf("%d\n",msum[1]); } return 0;}
0 0
- 九度OJ 题目1496:数列区间 (线段树 区间合并 +成段更新)
- POJ 3667 Hotel 线段树 区间合并(成段更新)
- POJ 3667(线段树,区间合并,成段更新)
- UESTC 1546(线段树,成段更新,区间合并)
- hdu 4893(线段树 成段更新+区间合并)
- 线段树 成段更新区间操作
- 线段树,成段更新,区间求和
- 线段树区间更新+区间合并
- 线段树的区间更新区间合并
- HDOJ 3911 Black And White 线段树 区间合并 成段更新
- Poj 1823 Hotel (线段树 区间合并 成段更新)
- poj 3667 Hotel(线段树,成段更新,区间合并,Lazy思想)
- HDU 3397 Sequence operation (线段树,成段更新,区间合并)
- 线段树 区间更新(成段更新) HDU1698
- POJ 3468 【线段树区间更新-成段更新】
- [UESTC]Another LCIS[线段树][区间合并][成段修改]
- 九度OJ题目1554:区间问题
- 九度 oj 题目1554:区间问题
- nginx - 性能优化,突破十万并发
- DNS原理及其解析过程【精彩剖析】
- Javascript 严格模式详解
- java多线程
- (win7 UEFI安装)顺便说说UEFI、GPT和Secure Boot
- 九度OJ 题目1496:数列区间 (线段树 区间合并 +成段更新)
- 免费阿里云服务器ECS初探
- 机房—组合查询
- 周赛二 CodeForces 545A
- Android基础之进程的优先级
- 【004.Matlab基础 数组寻址与处理 】
- 树状数组 hdu2838 Cow Sorting
- 确定比赛名次(拓扑排序模板(比之前的模板纠正和完善了,之前的会有bug,一些题有时会wa))
- TCP连接时需要进行三次握手?