題意:選取a序列的一段【l,r】將選中的區間按非降排序。問能否經過若干次操作後形成b序列;
分析:b序列的數的總類及各個類的數目一定要與a序列相同;
對b的每個位置的值,找到與之相同的a序列中還沒有被用的位置nowpos,然後判斷1到nowpos的最小值是否等於b序列的當前值,再將該位置修改為無效值;
若有一步不成功則輸出no,否者yes;
#includeusingview codenamespace
std;
const
int m=3e5+5
;const
int inf=0x3f3f3f3f
;int tree[m<<2
],a[m],b[m],aa[m],bb[m],ll[m];
vector
pos[m];
void up(int
root)
void build(int root,int l,int
r)
int midd=(l+r)>>1
; build(root
<<1
,l,midd);
build(root
<<1|1,midd+1
,r);
up(root);
}int query(int l,int r,int root,int l,int
r)
int midd=(l+r)>>1
;
int ans=inf;
if(l<=midd)
ans=min(ans,query(l,r,root<<1
,l,midd));
if(r>midd)
ans=min(ans,query(l,r,root<<1|1,midd+1
,r));
return
ans;
}void update(int nowpos,int x,int root,int l,int
r)
int midd=(l+r)>>1
;
if(midd>=nowpos)
update(nowpos,x,root
<<1
,l,midd);
else
update(nowpos,x,root
<<1|1,midd+1
,r);
up(root);
}int
main()
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)
sort(aa+1,aa+1+n);
sort(bb+1,bb+1+n);
int flag=0
;
for(int i=1;i<=n;i++)
}if(flag)
build(
1,1,n);
/*for(int i=1;i<=n*2;i++)
cout
for(int i=1;i<=n;i++)
//cout<
,n);
}if(flag)
puts("no
");else
puts(
"yes");
}return0;
}
線段樹 數列操作
假設有一列數 1 i n 支援如下兩種操作 1 將 ak 的值加 d k,d 是輸入的數 2 輸出 as as 1 at s,t 都是輸入的數,s t 根據操作要求進行正確操作並輸出結果。輸入格式 輸入檔案第一行乙個整數n 0 n 100000 第二行為 n 個整數,表示 的初始值。第三行為乙個整數...
操作格仔 線段樹
問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p...
線段樹操作格仔
有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p,x,y,...