1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #include <bits/stdc++.h> using namespace std; typedef long long ll;
#define endl '\n' #define Turnoff std::ios::sync_with_stdio(false)
const int Max=2e5+5; const int Mod=998244353; const int inf=0x3f3f3f3f;
#ifdef __DEBUG__ #define DeBug(format, ...) \ { \ fprintf(stdout, "[%s:%d]" format "", \ __FUNCTION__ , __LINE__, ##__VA_ARGS__); \ } #else #define DeBug(format,...) #endif
class SegTree{ public: #define Mid ((L+R)>>1) #define Leftson now<<1 #define Rightson now<<1|1 struct segtree{int L,R,minn,lazy;}; segtree tree[Max<<2]; void push_up(int now){ tree[now].minn=min(tree[Leftson].minn,tree[Rightson].minn); return; } void build(int L,int R,int now=1){ tree[now]={L,R,0,0}; if(L==R)return; build(L,Mid,Leftson); build(Mid+1,R,Rightson); push_up(now); return; } void updata(int qL,int qR,int val,int now=1){ if(qL<=tree[now].L&&qR>=tree[now].R){ tree[now].minn+=val; return; } if(qL<=tree[Leftson].R)updata(qL,qR,val,Leftson); if(qR>=tree[Rightson].L)updata(qL,qR,val,Rightson); push_up(now);return; } int query(int qL,int qR,int now=1){ if(qL>qR)return inf; if(tree[now].R<=qR&&tree[now].L>=qL)return tree[now].minn; int minn=inf; if(tree[Leftson].R>=qL)minn=min(minn,query(qL,qR,Leftson)); if(tree[Rightson].L<=qR)minn=min(minn,query(qL,qR,Rightson)); push_up(now); return minn; } }Min;
int arr[Max]; map<int,int>per,suf; int pos[Max];
int main(void){ int t;cin>>t; while(t--){ int n;cin>>n; Min.build(1,n); suf.clear(),per.clear(); for(int i=1;i<=n;i++){ cin>>arr[i]; pos[i]=n+1; suf[arr[i]]=n+1; Min.updata(i,i,arr[i]); } int maxn=0; for(int i=n;i>=1;i--){ pos[i]=suf[arr[i]]; maxn=max(maxn,arr[i]); suf[maxn]=i; } maxn=0; int x=0,y=0,z=0; for(int i=1;i<=n;i++){ maxn=max(maxn,arr[i]); int L=per[arr[i]],R=pos[i]; per[maxn]=i; if(R>n||L<1)continue; if(Min.query(L+1,R-1)==arr[i]){ x=L,y=R-L-1,z=n-R+1; } } if(x){ cout<<"YES"<<endl; cout<<x<<" "<<y<<" "<<z<<endl; } else cout<<"NO"<<endl; } }
|