hdu 1751 中文题
题意略 模板题
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define Max 200100
struct node{
int l,r,max;
};
node tree[Max<<2];
int ans;
int maxl(int x,int y)
{
return x>y?x:y;
}
void buildTree(int l,int r,int id)
{
tree[id].l=l;
tree[id].r=r;
tree[id].max=-1;
if(l==r)
return;
else
{
int mid=(l+r)>>1;
buildTree(l,mid,id<<1);//左子树[l,mid]
buildTree(mid+1,r,id<<1|1);//右子树[mid+1,r]
}
}
void update(int l,int value,int id)
{
if(tree[id].l==tree[id].r&&tree[id].l==l)
{
tree[id].max=value;
return;
}
int mid=(tree[id].l+tree[id].r)>>1;
if(l<=mid)
update(l,value,id<<1);
else
update(l,value,id<<1|1);
tree[id].max=maxl(tree[id<<1].max,tree[id<<1|1].max);//将左右儿子的值更新到根节点
}
void query(int l,int r,int id)
{
if(tree[id].l==l&&tree[id].r==r)
{
ans=maxl(ans,tree[id].max);
return;
}
int mid=(tree[id].l+tree[id].r)>>1;
if(r<=mid)
return query(l,r,id<<1);
else if(l>mid)
return query(l,r,id<<1|1);
else
{
query(l,mid,id<<1);
query(mid+1,r,id<<1|1);
}
}
int main()
{
int n,m,value;
char a;
int c,b;
char str[5];
int x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
buildTree(1,n,1);
for(int i=1;i<=n;i++)
{
scanf("%d",&value);
update(i,value,1);
}
for(int i=0;i<m;i++)
{
getchar();//吃掉换行
scanf("%c%d%d",&a,&b,&c);
if(a=='U')
update(b,c,1);
else
{
ans=0;
query(b,c,1);
printf("%d\n",ans);
}
}
}
return 0;
}
hdu 1166 敌兵布阵
题意略 也是模板题
#include <stdio.h>
#include <iostream>
#include <string.h>
#define maxn 50050
using namespace std;
struct Tree{
int l,r,sum;
};
int ans;
int date[maxn];//可删
Tree tree[maxn*4];
void BuildTree(int l,int r,int index)
{
tree[index].l=l;
tree[index].r=r;
tree[index].sum=0;
if(l==r)
{
return;
}
else
{
int mid=(l+r)>>1;
BuildTree(l,mid,index<<1);
BuildTree(mid+1,r,index<<1|1);
}
}
void InsertAdd(int l,int value,int index)//营地加人
{
if(tree[index].l==tree[index].r&&tree[index].l==l)
{
tree[index].sum+=value;
return;
}
int mid=(tree[index].l+tree[index].r)>>1;
if(l<=mid)
InsertAdd(l,value,index<<1);
else
InsertAdd(l,value,index<<1|1);
tree[index].sum=tree[index<<1].sum+tree[index<<1|1].sum;//将左右儿子的值更新到根节点
}
void InsertReduce(int l,int value,int index)//营地减人
{
if(tree[index].l==tree[index].r&&tree[index].l==l)
{
tree[index].sum-=value;
return;
}
int mid=(tree[index].l+tree[index].r)>>1;
if(l<=mid)
InsertReduce(l,value,index<<1);
else
InsertReduce(l,value,index<<1|1);
tree[index].sum=tree[index<<1].sum+tree[index<<1|1].sum;//将左右儿子的值更新到根节点
}
//减人可用加人的更新,只需在更新时添加-即可
void Query(int l,int r,int index)
{
if(tree[index].l==l&&tree[index].r==r)
{
ans+=tree[index].sum;
return;
}
int mid=(tree[index].l+tree[index].r)>>1;
if(r<=mid)
return Query(l,r,index<<1);
else if(l>mid)
return Query(l,r,index<<1|1);
else
{
Query(l,mid,index<<1);
Query(mid+1,r,index<<1|1);
}
}
int main()
{
int t;
cin >> t;
int value;
int l,r;
char a[100];int time=1;//刚接触线段树,这题wa时以为是上面敲错了,经历了无数次wa才发现控制Case的变量给我设置在while里面T_T
while(t--)
{
cout << "Case " << time++ << ":" << endl;
int index;
cin >> index;
BuildTree(1,index,1);
for(int i=1;i<=index;i++)
{
scanf("%d",&date[i]);
InsertAdd(i,date[i],1);
}
for(;;)
{
scanf("%s",a);
if(a[0]=='E')
break;
scanf("%d%d",&l,&r);
if(a[0]=='A') InsertAdd(l,r,1);
else if(a[0]=='S') InsertReduce(l,r,1);//InsertADD(l,-r,1);
else
{
ans=0;
Query(l,r,1);
printf("%d\n",ans);
}
}
}
return 0;
}