需要验证子数组是否与查询有关

时间:2019-05-22 19:34:09

标签: c++ dynamic-programming binary-search

这是问题的链接-

https://codeforces.com/contest/279/problem/C

将为您提供n个整数的数组。给出q个查询。在每个查询中,您将获得2个整数。您需要报告由这两个整数组成的子数组是否形成双音序列。元素可以相等。它不必严格增加或严格减少。 n和q是10^5的顺序。

我的方法是,找到可能出现音调序列的范围。我通过构造数组d来使用它。如果发现反转,我将替换d中的位。因此,对于{1,2,1,3,3,5,2,1}数组,d将为{0,1,0,1,1,1,0,0}。从这个数组中,我获得了可以存在有效双音序列的范围。当我找到前一个零的范围限制时,范围限制结束,并且范围限制从一个后的第一个零开始。因此,对于以上示例,范围将为{(1,3),(3,8)}。因此,如果查询位于上述范围之一,则答案存在。

我不知道为什么这个逻辑会失败。任何其他解决方案将不胜感激,但我想知道为什么这是错误的。

这是我的尝试。

https://codeforces.com/contest/279/submission/54424453

#include <cmath>
#include <cstdio>
#include <vector>
#include <list>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stack>
#include <queue>
#include <iterator>
#include <map>
#include <unordered_map>
#include <set>
#define fast ios_base::sync_with_stdio(false)
#define ll long long int
#define ld long double
#define vi vector<long long int>
#define vvi vector<vi >
#define pi pair<ll,ll>
#define vpi vector<pi >
#define vs vector<string>
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define pb push_back
#define forn(i,a,b,c) for(ll i=a;i<b;i+=c)
#define forb(i,a,b,c) for(ll i=a;i>=b;i-=c)
#define print(v) for(ll it=0;it<v.size();it++) cout<<v[it]<<" ";cout<<endl
#define printp(v) for(ll it=0;it<v.size();it++) cout<<v[it].first<<" "<<v[it].second<<endl
using namespace std;
vpi a;
int bincheck(ll x,ll y){
    ll l,r,m,c=0;
    l=0,r=a.size()-1;
    if(x>=a[r].first&&y<=a[r].second) return 1;
    while(c<30){
        m=(l+r)/2;
        if(x>=a[m].first&&x<=a[m].second&&x<=a[m+1].first){
            if(y<=a[m].second) return 1;
            return 0;
        }
        else if(x<a[m].first) r=m;
        else l=m;
        c++;
    }
    return 0;
}
int main(){
    ll n,q,l,r,i,tl;
    cin>>n>>q;
    vi v(n),d(n,0);
    for(i=0;i<n;i++) cin>>v[i];
    if(n>2){
        if(v[1]<v[0]) d[0]=1;
        for(i=1;i<n;i++){
            if((v[i]>v[i-1]&&d[i-1])||v[i]==v[i-1]) d[i]=d[i-1];
            else if(v[i]>v[i-1]) d[i]=1;
            else d[i]=0;
        }
        l=1,r=tl=0;
        for(i=1;i<n-1;i++){
            if(!d[i]&&!tl) tl=i+1;
            if(!d[i]&&d[i+1]){
                while(v[tl]<v[tl-1]) tl++;
                r=i+1;
                a.pb(make_pair(l,r));
                l=tl;
                tl=0;
            }
        }
        a.pb(make_pair(l,n));
    }
    //print(d);
    //printp(a);
    //cout<<endl;
    while(q--){
        cin>>l>>r;
        if(r-l<2) printf("Yes\n");
        else{
            if(bincheck(l,r)) printf("Yes\n");
            else printf("No\n");
        }
    }
}

0 个答案:

没有答案