HihoCoder 1236 Scores (五维偏序bitset+分块)

来源:互联网 发布:js trigger事件 编辑:程序博客网 时间:2024/06/06 12:05

题意:
五维偏序问题,在给出的五维向量中,m次询问有多少个是完全偏序

看了qsc大牛的代码才知道偏序问题还可以这样做…
大概是这么回事,对于每一维我们这样预处理它:
1.排序,分块
2.bitset存储下标状态,每个块的bitset存储前缀状态(方便后面询问处理结果)
对于每次询问,二分查找每一维对应的下标,那么这个下标前面所有的块都是答案,这样的得到的五个答案用bitset &操作一下就可以了。

#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>#include<bitset>//#pragma comment(linker, "/STACK:1024000000,1024000000");using namespace std;#define INF 0x3f3f3f3f#define maxn 50005int n,m;struct node{    int val;    int index;} a[6][50005];int block,num,belong[maxn],l[maxn],r[maxn];bitset<50005>b[6][250],res[6];bool cmp(node A,node B){    return A.val<B.val;}void init(){    for(int i=1; i<=5; i++)    {        sort(a[i]+1,a[i]+n+1,cmp);    }    block=sqrt(n);    num=n/block;    if(n%block) num++;    for(int i=1; i<=n; i++)    {        belong[i]=(i-1)/block+1;    }    for(int i=1; i<=num; i++)    {        l[i]=(i-1)*block+1;        r[i]=i*block;        for(int j=1; j<=5; j++)            b[j][i].reset();    }    for(int i=1; i<=5; i++)    {        for(int j=1; j<=num; j++)        {            b[i][j]|=b[i][j-1];            for(int k=l[j]; k<=r[j]; k++)            {                b[i][j].set(a[i][k].index);            }        }    }}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        for(int i=1; i<=n; i++)        {            for(int j=1; j<=5; j++)            {                scanf("%d",&a[j][i]);                a[j][i].index=i;            }        }        init();        int q;        scanf("%d",&q);        int ans=0;        int now[6];        while(q--)        {            for(int i=1; i<=5; i++) scanf("%d",&now[i]),now[i]^=ans;            for(int i=1; i<=5; i++)            {                res[i].reset();                int x=1,y=n;                while(x<=y)                {                    int mid=x+y>>1;                    if(a[i][mid].val<=now[i]) x=mid+1;                    else y=mid-1;                }                int pos=--x;                for(int j=l[belong[pos]];j<=pos;j++)                {                    res[i].set(a[i][j].index);                }                res[i]|=b[i][belong[pos]-1];            }            res[0]=res[1]&res[2]&res[3]&res[4]&res[5];            printf("%d\n",ans=res[0].count());        }    }    return 0;}
0 0
原创粉丝点击