• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

关键观察:小于\(2^k\)的数两两取或的最小值一定由前\(k 1\)小的一对组成。

证明采用数学归纳法:

对于\(k=1\),显然成立。

假设对于\(k\)结论成立,那么下面证明对于\(k 1\)也成立。

对于所有数的第\(k\)位都是\(1\),那么答案的第\(k\)位一定是\(1\),于是只要考虑\(k - 1\)位组成的最小值,所以需要\(k 1\)个数。

对于所有数中有超过\(2\) 个数的第\(k\)位为\(0\),那么答案第\(k\)位一定为\(0\),只要考虑\(k - 1\)位组成的最小值,同理需要\(k 1\)个数。

对于所有数中只有一个第\(k\)位为\(0\),那么答案第\(k\)位一定为\(1\),我们只要考虑第\(k\)位上为\(1\) 的\(k 1\)个数,然后再加上一个第\(k\)位为\(0\) 的数,需要\(k 2\)个数。

证毕。

于是用线段树维护最小值,每次查前\(31\) 小值,暴力求解。时间复杂度为\(\ mathcal { o }(TN \ log n TQ \ cdot 31^2 \ log n)\),慢出大便了。

#包含位/标准数据h。

#首先定义船方不负担装货费用

#定义硒秒

#定义mp std:make_pair

typedef long long ll

# define GC()(_S==_T(_ T=(_ S=_ B)fread(_ B,1,1 20,stdin),_ S==_ T)?EOF : *_S)

char _B[1 20],*_S=_B,* _ T=_ B;

int rd() {

int x=0,f=0;char ch=GC();

while(ch ' 0 ' | | ch ' 9 ')(ch=='-')(f=1),ch=GC();

while(ch='0' ch='9') x=x * 10 ch - '0 ',ch=GC();

返回f?-x : x;

}

const int N=1e5 10

int n,q,a[N],CNT=0;

结构节点{

int l,r;

std:pairint,int v;

节点*ls,* rs

} tr[N ^ 2],* rt

std:pairint,int ret[32];

空的上推(node *o) {

o - v=std:min(o - ls - v,o-RS-v);

}

void build(node *o,int l,int r) {

o - l=l,o-r=r;

if(l==r) {

o - v=mp(a[l],l);

返回;

}

int mid=(l r)1;

o - ls=tr[ cnt],o-RS=tr[CNT];

build(o - ls,l,mid),build(o - rs,mid 1,r),俯卧撑(o);

}

void upd(node *o,int p,int k) {

if(o - l==o - r) {

o - v=mp(k,p);

返回;

}

int mid=(o-l o-r)1;

if(p=mid) upd(o - ls,p,k);

else upd(o - rs,p,k);

俯卧撑(o);

}

std:pairint,int qry(node *o,int ql,int qr) {

if(ql=o - l o - r=qr)返回o-v;

int mid=(o-l o-r)1;

std:pairint,int ret=mp(1 30,1 30);

if(ql=mid)ret=STD :min(ret,qry(o - ls,QL,QR));

if(QR mid)ret=STD :min(ret,qry(o - rs,ql,QR));

返回浸水使柔软

}

void solve() {

n=rd();

for(int I=1;I=n;I)a=rd();

cnt=0,rt=tr[0],build(rt,1,n);

q=rd();

int tot=0;

for(int _=1;_=q;_) {

int l=rd(),r=rd(),up=std:min(31,r-l 1);

tot=0,memset(ret,0,sizeof(ret));

for(int I=1;我=向上;i) ret[ tot]=qry(rt,l,r),

upd(rt,ret[tot].se,1 30);

int ans=1 30

for(int I=1;I=toti)for(int j=I ^ 1;j=totj)

ans=std:min(ans,ret).返回,返回.fi);

printf('%d\n ',ans);

for(int I=1;i=toti) upd(rt,ret.se,a[ret]I .se]);

}

}

int main() {

for(int _=rd();_;_-)solve();

返回0;

}

Link to comment
Share on other sites