zoukankan      html  css  js  c++  java
  • 2015年北京网络赛 J Clarke and puzzle 求五维偏序 分块+bitset

    题目

    Description
    Kyle is a student of Programming Monkey Elementary School. Just as others, he is deeply concerned with his grades.

    Last month, the school held an examination including five subjects, without any doubt, Kyle got a perfect score in every single subject.

    There are n students took part in this examination(not including Kyle), and everyone got an integer between 1 to m as the score of one subject.

    Now, looking at the grade table of these n students, Kyle wants to know how many students still did no better than him even if his scores are something else – Here, “no better” means there is no subject in which the student got strictly greater score than Kyle.

    Input
    There are multiple test cases.

    The first line of the input contains an integer T (T <= 3) which means the number of test cases.

    The first line of each test case contains two integers, n, m(n, m≤ 50,000), which are the number of students and the perfect score of each subject.

    In the next n lines, each line consists of five integers, indicating a student’s scores.

    Then one line follows. This line contains an integer q(q≤ 50,000) indicating the number of queries.

    In the next q lines, each line contains five integers as well, representing a query. Each query indicates a set of scores, and for each query, you should figure out that if Kyle's grade is this set of scores, how many students still did no better than him. But for the sake of security, only the first query is in its original form, and other queries are encrypted. To decrypt a query, you must let each integer in the query do xor operation with the answer of last query. It's guaranteed that all the decrypted queries contain integers between 1 and 50000.

    Output
    For each test case, you should output q lines as the answer for all queries.
    Sample Input
    2
    2 3
    1 1 1 1 1
    2 2 2 2 2
    2
    1 1 1 1 1
    3 3 3 3 3
    3 5
    1 1 1 1 1
    1 1 1 1 1
    1 2 3 4 5
    2
    1 1 1 1 1
    1 1 1 1 1
    Sample Output

    1
    2
    2
    2
    HINT

    In case 1, there are two students with different scores and the scores of the first student (1, 1, 1, 1, 1) are not larger than the first query (1 1 1 1 1) in every subject, so the answer for this query is 1.

    After having xor operation with the last answer 1, the second query (3,3,3,3,3) will be decrypted into (2, 2, 2, 2, 2). Because both students’ scores are no better than (2, 2, 2, 2, 2), so the answer for query 2 is 2.

    题解

    因为每次询问都要和上次询问异或,所以这个题目是道强制在线的题目,那么我们应该如何解决呢,首先我们知道这个题目是一个裸的五位偏序的题目,那么二维三维的偏序大家应该都知道,就是用树状数组和cdq分治,那么这道题目的话,强制在线,cdq分治失效,那么我们一个如何去做呢,首先我们肯定考虑暴力,那么大概的做法就是存下每一维的状态,然后询问的时候,取查询每一维前面的一个状态,然后相与,那么就可以得到答案了,但是复杂度爆了,那么我们看看如何优化,分块大法吼啊!!然后的话我们发现,每一个块代表的状态是可以从前面转移过来的,并且要做一系列的位运算,那么我们使用bitset来压位就好了。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<bitset>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef unsigned long long ull;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    typedef vector <int> VI;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
    void check_max (int &a,int b) { a=max (a,b);}
    void check_min (int &a,int b) { a=min (a,b);}
    const int maxn=5e4+10;
    int n,m;
    struct node {
        int x,y;
    }a[6][maxn];
    bool cmp (node a,node b) {
        return a.x<b.x;
    }
    int now[7];
    bitset <maxn> b[7][270];
    bitset <maxn> ans[7];
    int l[300],r[300];
    int belong[maxn];
    
    
    void solve () {
        scanf ("%d%d",&n,&m);
        rep (i,1,5) 
         rep (j,1,250) b[i][j].reset ();
        rep (i,1,n) 
         rep (j,1,5)  {
            scanf ("%d",&a[j][i].x);
            a[j][i].y=i;
        } 
        rep (i,1,5) sort (a[i]+1,a[i]+1+n,cmp);
        int block=sqrt (n);
        int num=n/block; if (n%block) num++;
        rep (i,1,num) l[i]=block*(i-1)+1,r[i]=i*block;
        r[num]=n;
        rep (i,1,n) belong[i]=(i-1)/block+1;
        rep (i,1,5) 
         rep (j,1,num) {
            b[i][j]|=b[i][j-1];
            rep (k,l[j],r[j]) b[i][j][a[i][k].y]=1;
        }
        int q;
        scanf ("%d",&q);
        int lastans=0;
        while (q--) {
           rep (i,1,5) scanf ("%d",&now[i]);
           rep (i,1,5) now[i]^=lastans;
           rep (i,1,5) ans[i].reset ();
           rep (i,1,5) {
               int L=0,R=n;
               while (L<=R) {
                   int mid= (L+R)>>1;
                   if (now[i]>=a[i][mid].x) L=mid+1;
                   else R=mid-1;
               }
               int p=L-1;
               if (p==0) continue;
               ans[i]|=b[i][belong[p]-1];
               rep (j,l[belong[p]],p) ans[i][a[i][j].y]=1;
           }
           ans[1]=ans[2]&ans[2]&ans[3]&ans[4]&ans[5];
           lastans=ans[1].count ();
           printf ("%d
    ",lastans);
        } 
    
        return ;
    }
    
    int main () {
        int t;
        scanf ("%d",&t);
        while (t--) {
            solve ();
        }
        return 0;
    }
    
  • 相关阅读:
    Datawhale编程实践(LeetCode 腾讯精选练习50)Task2
    Datawhale编程实践(LeetCode 腾讯精选练习50)Task1
    关于深度学习中样本权重取0的问题
    对多维numpy数组使用random.shuffle的问题
    Ubuntu18.04LTS左上角光标闪烁原因之一:NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver.
    pycharm 报错ImportError: could not import module 'PySide2.QtWidgets'
    pyinstaller 打包pyside2项目遇到plugins window问题
    git pull的时候出错: Git Couldn't reserve space for cygwin's heap
    angularjs鼠标移入移出实现显示隐藏
    gulp编译出现Cannot find module 'internal/util/types'——node环境的变更
  • 原文地址:https://www.cnblogs.com/hhlya/p/13869240.html
Copyright © 2011-2022 走看看