您的位置:首页 > 理论基础 > 数据结构算法

【线段树+离散化】Uestc-数据结构专题训练【B】

2016-04-22 23:01 405 查看
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#define inf 0x3f3f3f3f
#define LL unsigned long long
#define left_child now<<1,l,mid
#define right_child now<<1|1,mid+1,r
using namespace std;
int n,q;
struct node{
int l,r;
long long tot;
bool lazy;
}e[100010*4];
int map[100010*3],map2[100010*3],Hashhash[100010*3];
int k=1;
int a,b,c,m;
int op[100010];
int Left[100010];
int Right[100010];
int f(int u)
{
int now=0;
now = lower_bound(map + 1,map + 1 + m,u) - map;
return now;
}
void build(int now,int l,int r)
{
e[now].l=l,e[now].r=r;
if(l==r)return;
int mid=(l+r)>>1;
build(left_child);
build(right_child);
}
void pushdown(int k)
{
e[k<<1].tot = map[e[k<<1].r]-map[e[k<<1].l-1];
e[k<<1].lazy=1;
e[k<<1|1].tot = map[e[k<<1|1].r]-map[e[k<<1|1].l-1];
e[k<<1|1].lazy=1;
e[k].lazy=0;
}
void update(int now,int l,int r,int x,int y)
{
if(map[x-1]+1<=map[l-1]+1&&map[r]<=map[y])
//	if(x<=l&&r<=y)
{
e[now].tot=map[r]-map[l-1];
e[now].lazy=1;
return ;
}
//	if(e[now].lazy==1)pushdown(now);
if(e[now].lazy==1)return ;
int mid=(l+r)>>1;
if(y<=mid)
{
update(now<<1,l,mid,x,y);
}
else if(x>mid)
{
update(now<<1|1,mid+1,r,x,y);
}
else
{
update(now<<1,l,mid,x,y);
update(now<<1|1,mid+1,r,x,y);
}
e[now].tot=e[now<<1].tot+e[now<<1|1].tot;
}
int query(int now,int l,int r,int x,int y)
{
if(map[x-1]+1<=map[l-1]+1&&map[r]<=map[y])
//	if(x<=l&&r<=y)
{
return e[now].tot;
}
int mid=(l+r)>>1;
if(e[now].lazy==1)return min(map[r],map[y])-max(map[l-1]+1,map[x-1]+1)+1;
//	if(e[now].lazy==1)pushdown(now);
if(y<=mid)return query(now<<1,l,mid,x,y);
else if(x>mid)return query(now<<1|1,mid+1,r,x,y);
else
{
return query(now<<1,l,mid,x,mid)+query(now<<1|1,mid+1,r,mid+1,y);
}
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&a,&b,&c);
op[i]=a;
Left[i]=b;
Right[i]=c;
map[k++]=b-1;
map[k++]=c;
}
for(int i=1;i<=2*q;i++)map2[i]=map[i];
sort(map+1,map+k);
m= unique(map+1,map+k)-map-1;//去重后有M个
for(int i = 1;i <= m;++i)Hashhash[i] = i;
build(1,1,m);
map[0]=0;
for(int i=1;i<=q;i++)
{
if(op[i]==1)
{
update(1,1,m,f(Left[i]),f(Right[i]));
//	update(1,1,m,Left[i],Right[i]);
}
else
{
printf("%d\n",Right[i]-Left[i]+1-query(1,1,m,f(Left[i]),f(Right[i])));
//  printf("%d\n",Right[i]-Left[i]+1-query(1,1,m,Left[i],Right[i]));
}
}
return 0;
}

自己的代码。

另贴一大神的代码。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<vector>
using namespace std;
int n,q;
struct Q
{
int op,l,r;
}ques[100000+10];
vector<int>stable;
int m;
struct T
{
int l,r;
int sum;
bool flag;//这道题的特殊性质,可以不用标准的lazy处理方法
}tree[100000*8+10];
void build(int id,int l,int r)
{
tree[id].l=l;tree[id].r=r;tree[id].flag=0;
if(l==r)return;
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
}
void update(int id,int l,int r)
{
if(l<=stable[tree[id].l-1]+1&&stable[tree[id].r]<=r)
{
tree[id].flag=true;tree[id].sum=stable[tree[id].r]-stable[tree[id].l-1];
return;
}
if(tree[id].flag)return;
int mid=tree[id].l+tree[id].r>>1;
if(l<=stable[mid])update(id<<1,l,r);
if(r>stable[mid])update(id<<1|1,l,r);
tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
}
int query(int id,int l,int r)
{
if(l<=stable[tree[id].l-1]+1&&stable[tree[id].r]<=r)
{
//		cerr<<stable[tree[id].l-1]+1<<" "<<stable[tree[id].r]<<endl;
return tree[id].sum;
}
if(tree[id].flag)
{
return min(r,stable[tree[id].r])-max(l,stable[tree[id].l-1]+1)+1;
}
int ret=0;
int mid=tree[id].l+tree[id].r>>1;
if(l<=stable[mid])ret+=query(id<<1,l,r);
if(r>stable[mid])ret+=query(id<<1|1,l,r);
return ret;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&ques[i].op,&ques[i].l,&ques[i].r);
stable.push_back(ques[i].l-1);
stable.push_back(ques[i].r);
}
//stable.push_back(0);
sort(stable.begin(),stable.end());
stable.erase(unique(stable.begin(),stable.end()),stable.end());
m=stable.size()-1;
//	for(int i=1;i<=m;i++)printf("  %d",stable[i]);printf("\n");
build(1,1,m);
for(int i=1;i<=q;i++)
{
if(ques[i].op==1)update(1,ques[i].l,ques[i].r);
else printf("%d\n",ques[i].r-ques[i].l+1-query(1,ques[i].l,ques[i].r));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: