您的位置:首页 > 其它

线段树小结

2016-07-28 17:25 393 查看
今天练了一天的线段树的(水)题,在此做一些总结.

A hdu1754 I Hate It

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1754

单点更新+区间查询

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int n,m,a,b;
int sum[800005];
char t;
void pushup(int rt)
{
sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}
void build(int rt,int l,int r)
{
if(l==r)
{
scanf("%d",&sum[rt]);
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int rt,int l,int r,int q,int x)
{
if (l==r)
{
sum[rt]=x;
return;
}
int mid=(l+r)>>1;
if (q<=mid)update(lson,q,x);
else update(rson,q,x);
pushup(rt);
}
int query(int rt,int l,int r,int x,int y)
{
if (l>=x&&r<=y)
{
return sum[rt];
}
int mid=(l+r)>>1;
int ans=0;
if (x<=mid)ans=max(ans,query(lson,x,y));
if (y>mid)ans=max(ans,query(rson,x,y));
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
build(1,1,n);
getchar();
for (int i=1;i<=m;i++)
{
scanf("%c%d%d",&t,&a,&b);
if (t=='U') {update(1,1,n,a,b);}
if (t=='Q') {printf("%d\n",query(1,1,n,a,b));}
getchar();
}
}
return 0;
}


B HDU 1394 Minimum Inversion Number

传送门http://acm.hdu.edu.cn/showproblem.php?pid=1394

线段树求逆序对(暴力或归并排序均可)

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int sum[20005],n,a[5005],x;
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int rt,int l,int r)
{
if (l==r)
{
sum[rt]=0;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int query(int rt,int l,int r,int x,int y)
{
if (l>=x&&r<=y)
{
return sum[rt];
}
int mid=(l+r)>>1;
int ans=0;
if (x<=mid) ans+=query(lson,x,y);
if (y>=mid) ans+=query(rson,x,y);
return ans;
}
void update(int rt,int l,int r,int x)
{
if (l==r)
{
sum[rt]++;
return;
}
int mid=(l+r)>>1;
if (x<=mid) update(lson,x);
else update(rson,x);
pushup(rt);
}
int main()
{
while(~scanf("%d",&n))
{
build(1,1,n);
x=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
x+=query(1,1,n,a[i]+1,n);
update(1,1,n,a[i]+1);
}
int ans=x;
for (int i=1;i<=n;i++)
{
x+=n-a[i]-a[i]-1;
ans=min(ans,x);
}
printf("%d\n",ans);
}
}


C HDU 2795 Billboard

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2795

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int sum[800005],h,w,n,x;
void pushup(int rt)
{
sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}
void build(int rt,int l,int r)
{
if (l==r)
{
sum[rt]=w;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int query(int rt,int l,int r,int x)
{
int ret;
if (l==r)
{
sum[rt]-=x;
return l;
}
int mid=(l+r)>>1;
if (x<=sum[rt<<1]) ret=query(lson,x);
else ret=query(rson,x);
pushup(rt);
return ret;
}
int main()
{
while (~scanf("%d%d%d",&h,&w,&n))
{
int z=min(h,n);
build(1,1,z);
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
if (sum[1]<x) printf("-1\n");
else printf("%d\n",query(1,1,z,x));
}
}
}


D POJ 3468 A Simple Problem with Integers

传送门:http://poj.org/problem?id=3468

区间更新+查询

#include<cstdio>
#define lson u<<1,l,mid
#define rson u<<1|1,mid+1,r
#define maxn 200005
#define ll long long
struct node{
int l,r;
ll s;
ll add;
}nod[4*maxn];
int n,m;
void pushup(int u)
{
nod[u].s=nod[u<<1].s+nod[u<<1|1].s;
}
void build(int u,int l,int r)
{
nod[u].l=l;nod[u].r=r;
nod[u].add=0;
if(l==r)
{
scanf("%lld",&nod[u].s);
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(u);
}
void pushdown(int u)
{
nod[u<<1].add+=nod[u].add;
nod[u<<1|1].add+=nod[u].add;
nod[u<<1].s+=(nod[u<<1].r-nod[u<<1].l+1)*nod[u].add;
nod[u<<1|1].s+=(nod[u<<1|1].r-nod[u<<1|1].l+1)*nod[u].add;
nod[u].add=0;
}
void update(int u,int l,int r,int x,int y,ll add)
{
if(l==x&&r==y)
{
nod[u].s+=(r-l+1)*add;
nod[u].add+=add;
return;
}
if(nod[u].add) pushdown(u);
int mid=(l+r)>>1;
if(y<=mid) update(lson,x,y,add);
else if(x>mid) update(rson,x,y,add);
else
{
update(lson,x,mid,add);
update(rson,mid+1,y,add);
}
pushup(u);

}
ll query(int u,int l,int r,int x,int y)
{
if(x==l&&y==r) return nod[u].s;
if(nod[u].add) pushdown(u);
int mid=(l+r)>>1;
if(y<=mid) return query(lson,x,y);
else if(x>mid) return query(rson,x,y);
else
{
ll ans=0;
ans+=query(lson,x,mid);
ans+=query(rson,mid+1,y);
return ans;
}

}
int main()
{
int x,y;
char k;
ll z;
while (~scanf("%d%d",&n,&m))
{
build(1,1,n);
for(int i=1;i<=m;i++ )
{
getchar();
scanf("%c",&k);
if(k=='C')
{
scanf("%d%d%lld",&x,&y,&z);
update(1,1,n,x,y,z);
}
else if(k=='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
}
}
return 0;
}


E POJ 2528 Mayor’s posters

传送门:http://poj.org/problem?id=2528

基础离散化

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int t,n,sum[200005],ans,hash[10000005],l[10005],r[10005],a[20010],lazy[200005],f[20005];
void pushdown(int rt)
{
if (lazy[rt]!=0&&sum[rt]!=-1)
{
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
lazy[rt]=0;
sum[rt<<1]=sum[rt<<1|1]=sum[rt];
}

}
void pushup(int rt)
{
if (sum[rt<<1]==sum[rt<<1|1]) sum[rt]=sum[rt<<1];
else sum[rt]=-1;
}
void update(int rt,int l,int r,int x,int y,int add)
{
if (l>=x&&r<=y)
{
sum[rt]=add;
lazy[rt]=add;
pushdown(rt);
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if (x<=mid) update(lson,x,y,add);
if (y>mid) update(rson,x,y,add);
pushup(rt);
}
void query(int rt,int l,int r)
{
if (sum[rt]!=-1)
{
if (f[sum[rt]]!=1)
{
f[sum[rt]]=1;
ans++;
}
return;
}
int mid=(l+r)>>1;
query(lson);
query(rson);
}
int main()
{
scanf("%d",&t);
while (t--)
{
memset(sum,0,sizeof(sum));
memset(lazy,0,sizeof(lazy));
memset(f,0,sizeof(f));
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&l[i],&r[i]);
a[i*2-1]=l[i];
a[i*2]=r[i];
}
sort(a+1,a+1+n*2);
int t=0;
int pre=0;
for (int i=1;i<=2*n;i++)
{
if (a[i]!=pre)
{
pre=a[i];
t++;
hash[a[i]]=t;
}
}
for (int i=1;i<=n;i++)
{
update(1,1,t,hash[l[i]],hash[r[i]],i);
}
ans=0;
query(1,1,t);
printf("%d\n",ans);
}
}


F http://blog.csdn.net/chen20000804/article/details/52046017

区间开方求和

G http://blog.csdn.net/chen20000804/article/details/51137428

包含了N种操作的题,现在终于可以1h内切了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: