一道纯英语阅读题+线段树模板题(当然读懂了题才是~~)
题面太长,就不放出来了。
题意:给出N(最大1e5)组数据,每组数据包括一个 Ti [1,1e9] 和 Vi [1,1e4] ,其中Ti表示时间且严格递增,Vi代表该点的Val值,给出C [1,10] 个操作,每个操作包括 R(gt,lt),F(min,max,avg),L(int型整数)三个参数,比如输入的是 lt min 100,表示若某结点 i [1,N] 在时间范围为 [T[i]-100,T[i]) 注意开闭区间 的所有组数据中的最小值比V[i] 还小,则ans++;如果是 gt min 100,表示若某结点 i [1,N] 在时间范围为 [T[i]-100,T[i]) 注意开闭区间 的所有组数据中的最小值比V[i] 大,则ans++;其他情况以此类推。
思路:看懂题意后就知道是个简单的区间查询最值和区间求和的问题(对于求平均值直接换成求和就好),然后建三个线段树,分别记录区间min,max和sum就好了,详细看代码。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int T[maxn],V[maxn];
struct node
{
int Max,Min,Sum;
}tree[maxn<<2];
void push_up(int rt)
{
tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min);
tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
tree[rt].Sum=tree[rt<<1].Sum+tree[rt<<1|1].Sum;
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d%d",&T[l],&V[l]);
tree[rt].Max=V[l];
tree[rt].Min=V[l];
tree[rt].Sum=V[l];
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
push_up(rt);
}
int querymin(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return tree[rt].Min;
}
int mid=(l+r)>>1;
int ret=1e9;
if(L<=mid) ret=min(ret,querymin(L,R,lson));
if(R>mid) ret=min(ret,querymin(L,R,rson));
return ret;
}
int querymax(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return tree[rt].Max;
}
int mid=(l+r)>>1;
int ret=-1;
if(L<=mid) ret=max(ret,querymax(L,R,lson));
if(R>mid) ret=max(ret,querymax(L,R,rson));
return ret;
}
int querysum(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return tree[rt].Sum;
}
int mid=(l+r)>>1;
int ret=0;
if(L<=mid) ret+=(ret,querysum(L,R,lson));
if(R>mid) ret+=(ret,querysum(L,R,rson));
return ret;
}
int main()
{
int n,m;
while(~scanf("%d",&n))
{
build(1,n,1);
scanf("%d",&m);
char S1[5],S2[5];
int d,s,t,temp,ans;
while(m--)
{
scanf("%s%s%d",S1,S2,&d);
ans=0;
if(strcmp(S2,"min")==0)
{
for(t=2;t<=n;t++) //依次在【s,t】区间查找
{
temp=max(1,T[t]-d); //注意减后为负数的情况
s=lower_bound(T+1,T+1+n,temp)-T;
if(s>t-1) continue; //位置不合法跳过
if(S1[0]=='g') ans+=(V[t]>querymin(s,t-1,1,n,1));
else ans+=(V[t]<querymin(s,t-1,1,n,1));
}
}
else if(strcmp(S2,"max")==0)
{
for(t=2;t<=n;t++)
{
temp=max(1,T[t]-d);
s=lower_bound(T+1,T+1+n,temp)-T;
if(s>t-1) continue;
if(S1[0]=='g') ans+=(V[t]>querymax(s,t-1,1,n,1));
else ans+=(V[t]<querymax(s,t-1,1,n,1));
}
}
else if(strcmp(S2,"avg")==0)
{
for(t=2;t<=n;t++)
{
temp=max(1,T[t]-d);
s=lower_bound(T+1,T+1+n,temp)-T;
if(s>t-1) continue;
if(S1[0]=='g') ans+=(V[t]*(t-s)>querysum(s,t-1,1,n,1));
else ans+=(V[t]*(t-s)<querysum(s,t-1,1,n,1));
}
}
printf("%d\n",ans);
}
}
return 0;
}