51Nod 1577 异或凑数(线性基)

来源:互联网 发布:如何看待网络成瘾行为 编辑:程序博客网 时间:2024/05/18 03:26

Description

从左到右一共n个数,数字下标从1n编号。

一共m次询问,每次询问是否能从第L个到第R个数中(包括第L个和第R个数)选出一些数使得他们异或为K

数据量比较大。

输入请用挂

int read(){    int ans=0;    char last=' ',ch=getchar();    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();    return ans;}

输出请用puts

Input

单组测试数据。
第一行一个整数n(0<n500,000)
第二行n个整数,0<每个数<230
第三行一个数m,表示询问次数(0<m500,000)
接下来m行每行三个数,L,R,K(0<LRn,0<K<230)

Output

M行,每行为YESNO

Sample Input

5
1 1 2 4 6
3
1 2 1
2 4 8
3 5 7

Sample Output

YES
NO
NO

Solution

只要K可以被区间[L,R]的线性基表出则YES,问题在于如何预处理每个区间的线性基,考虑固定左端点的线性基,那么问题变为求从L开始的字典序最小的线性基,从n1枚举L,如果当前数和已有线性基无关则直接加入到线性基中,否则判断这个数的位置和其对应的基编号大小,如果当前数编号较小则将当前数加入基中,把原先的基拿出来继续消元即可

Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;namespace fastIO {    #define BUF_SIZE 100000    //fread -> read    bool IOerror=0;    inline char nc()     {        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;        if(p1==pend)         {            p1=buf;            pend=buf+fread(buf,1,BUF_SIZE,stdin);            if(pend==p1)             {                IOerror=1;                return -1;            }        }        return *p1++;    }    inline bool blank(char ch)     {        return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';    }    inline void read(int &x)     {        char ch;        while(blank(ch=nc()));        if(IOerror)return;        for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');    }    #undef BUF_SIZE};using namespace fastIO;typedef pair<int,int>P;const int maxn=500005;int n,m,a[maxn];struct node{    int val,pos;    node(){};    node(int _val,int _pos){val=_val;pos=_pos;}}base[maxn][30];int main(){    read(n);    for(int i=1;i<=n;i++)read(a[i]);    for(int l=n;l>=1;l--)    {        for(int i=0;i<=29;i++)base[l][i]=base[l+1][i];        node temp=node(a[l],l);        for(int i=29;i>=0;i--)            if((temp.val>>i)&1)            {                if(!base[l][i].val)                {                    base[l][i]=temp;                    break;                }                else                {                    if(temp.pos<base[l][i].pos)swap(base[l][i],temp);                    temp.val^=base[l][i].val;                }             }    }    read(m);    while(m--)    {        int l,r,k;        read(l);read(r);read(k);        for(int i=29;i>=0;i--)            if((k>>i)&1)            {                if(base[l][i].val==0||base[l][i].pos>r)break;                k^=base[l][i].val;            }        if(k)puts("NO");        else puts("YES");    }    return 0;}
原创粉丝点击