题意:给定n个数,m个区间l,r及一个位置p,l=<p<=r。问对区间排序后p位置元素是否改变
思路:判断p位置左端到l比p大的数,与p位置右端到r比p小的数。两个相等位置不变,否则变了
日了吉娃娃了,水题被我想得巨复杂,没想到这样也能过
#include<cstdio>
#include<cstring>
int a[10100];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int L,R,i;
for(int t=0;t<m;t++)
{
int cnt1,cnt2;
cnt1=cnt2=0;
scanf("%d%d%d",&L,&R,&i);
for(int j=i-1;j>=L;j--)
if(a[j]>a[i])cnt1++;
for(int j=i+1;j<=R;j++)
if(a[j]<a[i])cnt2++;
if(cnt1!=cnt2)
printf("No\n");
else
printf("Yes\n");
}
}
}
归并树:每个结点代表一段区间的排序,查询时如果查询区间不是在一个结点上,那么就合并所有涉及到查询区间的区间信息
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e4+5;
const int INF = 1e9+1;
struct tree
{
vector<int> v;
}node[maxn*4];
int a[maxn];
void build(int rt,int l,int r)
{
if(l==r)
{
node[rt].v.push_back(a[l]);
return;
}
int mid=(l+r)/2;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
merge(node[rt*2].v.begin(),node[rt*2].v.end(),//归并排序后放入父节点的区间中
node[rt*2+1].v.begin(),node[rt*2+1].v.end(),back_inserter(node[rt].v));
}
int query(int rt,int ql,int qr,int l,int r,int val)
{
if(l>r||ql>r||qr<l)return 0;
else if(ql<=l&&qr>=r)return lower_bound(node[rt].v.begin(),node[rt].v.end(),val)-
node[rt].v.begin();
int mid=(l+r)/2;
return query(rt*2,ql,qr,l,mid,val)+query(rt*2+1,ql,qr,mid+1,r,val);
}
int main()
{
int n,m;
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
int l,r,p;
for(int i=1;i<=4*n;i++)node[i].v.clear();
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
for(int t=0;t<m;t++)
{
scanf("%d%d%d",&l,&r,&p);
int aa=query(1,l,r,1,n,a[p]);
if(aa==(p - l))
puts("Yes");
else
puts("No");
}
}
}