Hiho coder 1236 2015 北京网络赛 Score

五维偏序。。一开始被吓到了,后来知道了一种BITSET分块的方法,感觉非常不错。

呆马:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <vector>
 7 #include <bitset>
 8 #define inf 1000000007
 9 #define maxn 52000
10 #define maxm 520
11 
12 using namespace std;
13 
14 struct score
15 {
16     int x,y;
17     friend bool operator <(score a, score b)
18     {
19         return a.x<b.x;
20     }
21 }s[6][maxn];
22 
23 int n,m,p,num,block;
24 int bel[maxn],l[maxm],r[maxm];
25 int a[6][maxn];
26 bitset<50005> b[6][maxm];
27 bitset<50005> now[6];
28 
29 int main()
30 {
31     int Case;
32     scanf("%d",&Case);
33     for (int i=1;i<=5;i++) b[i][0].reset();
34     for (int o=1;o<=Case;o++)
35     {
36         scanf("%d%d",&n,&m);
37         for (int j=1;j<=n;j++)
38             for (int i=1;i<=5;i++)    
39             {
40                 scanf("%d",&a[i][j]);
41                 s[i][j].x=a[i][j];
42                 s[i][j].y=j;
43             }
44         for (int i=1;i<=5;i++)
45         {
46             sort(s[i]+1,s[i]+n+1);
47             sort(a[i]+1,a[i]+n+1);
48         }
49         int block=sqrt(n);
50         int num=n/block+(n%block!=0);
51         for (int i=1;i<=n;i++) bel[i]=(i-1)/block+1;
52         for (int i=1;i<=num;i++) l[i]=(i-1)*block+1;
53         for (int i=1;i<=num;i++) r[i]=i*block;
54         r[num]=n;
55         for (int i=1;i<=5;i++)
56             for (int j=1;j<=num;j++)
57             {
58                 b[i][j]=b[i][j-1];
59                 for (int k=l[j];k<=r[j];k++)
60                     b[i][j][s[i][k].y]=1;
61             }
62         scanf("%d",&p);
63         int x[6],ans=0;
64         for (int q=1;q<=p;q++)
65         {
66             for (int i=1;i<=5;i++) scanf("%d",&x[i]);
67             for (int i=1;i<=5;i++) x[i]^=ans;
68             for (int i=1;i<=5;i++) now[i].reset();
69             for (int i=1;i<=5;i++)
70             {
71                 int tmp=upper_bound(a[i]+1,a[i]+n+1,x[i])-a[i]-1;
72                 if (tmp==0) continue;
73                 now[i]=b[i][bel[tmp]-1];
74                 for (int j=l[bel[tmp]];j<=tmp;j++)
75                     now[i][s[i][j].y]=1;
76             }
77             now[0]=now[1]&now[2]&now[3]&now[4]&now[5];
78             ans=now[0].count();
79             printf("%d\n",ans);
80         }
81     }
82     return 0;
83 }
Score

 

转载于:https://www.cnblogs.com/zig-zag/p/4852563.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值