hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题
2015-09-25 18:32
501 查看
题目大意:
每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数
因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案
先将学生按每一门成绩都排一次序
这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态
这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好
查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n)次了
最后将5次得到的答案进行与操作就可以了
每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数
因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案
先将学生按每一门成绩都排一次序
这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态
这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好
查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n)次了
最后将5次得到的答案进行与操作就可以了
#include<bits/stdc++.h> using namespace std; #define N 50001 #define pii pair<int,int> int n , m , q , block; bitset<N> bs[5][300]; //记录前缀或值和 pii val[5] ; void read() { scanf("%d%d" , &n , &m); for(int i=0 ; i<n ; i++){ for(int j=0 ; j<5 ; j++){ scanf("%d" , &val[j][i].first); val[j][i].second = i; } } for(int i=0 ; i<5 ; i++) sort(val[i] , val[i]+n); block = (int)sqrt(n+0.5); int i , j , k , index; for(i=0 ; i<5 ; i++){ for(j=0 , index=0 ; j<n ; j+=block , index++){ int last = min(j+block,n); bs[i][index].reset(); for(k=j ; k<last ; k++){ bs[i][index].set(val[i][k].second); } if(index) bs[i][index] |= bs[i][index-1]; // cout<<i<<" "<<j<<" "<<bs[i][index].to_string()<<endl; } } } int find_pos(int k , int x) { int l=0 , r=n-1 , ans=-1; while(r>=l){ int m=(l+r)>>1; if(val[k][m].first<=x) l=m+1 , ans=m; else r=m-1; } return ans; } bitset<N> getStatus(int k , int x) { int pos = find_pos(k , x); bitset<N> ans; if(pos<0) return ans.reset(); int len = (pos+1)/block; int st = block*len; if(len>=1) ans = bs[k][len-1]; else ans.reset(); for(int i=st ; i<=pos ; i++) ans.set(val[k][i].second); return ans; } void query() { int x , last=0; bitset<N> ans[5]; scanf("%d" , &q); while(q--){ for(int i=0 ; i<5 ; i++) ans[i].reset(); for(int i=0 ; i<5 ; i++){ scanf("%d" , &x); x ^= last; ans[i] = getStatus(i , x); if(i) ans[i] &= ans[i-1]; // cout<<i<<" "<<x<<" "<<ans[i].to_string()<<endl; } last = ans[4].count(); printf("%d\n" , last); } } int main() { // freopen("a.in" , "r" , stdin); int T; scanf("%d" , &T); while(T--){ read(); query(); } return 0; }
相关文章推荐
- Winsock网络编程
- C# 热敏打印机 Socket 网络链接 打印 图片 (二)
- LAMP组合的编译安装(httpd 2.4+mysql 5.5+php 5.4)
- CentOS6.6自带网卡驱动r8169与网卡芯片不匹配导致网络不通
- Linux下Socket网络编程send和recv使用注意事项
- Linux下Socket网络编程send和recv使用注意事项
- HTTPD配置文件MPM(非7.0以上版本)
- IOS HTTP同步异步
- HTTP Cookie详解
- IOS 网络,客户端,服务端
- 【.Net码农】腾迅股票数据接口 http/javascript
- IOS 请求网络数据,解析
- HttpClient和HtmlUnit的比较总结以及使用技巧(二)
- 卷积神经网络代码简单备注
- HttpClient和HtmlUnit的比较总结以及使用技巧(一)
- java网络编程(三) QQ聊天功能类似的C/S建立
- HTTP Live Streaming直播(iOS直播)技术分析与实现
- http错误码大全
- Python网络爬虫
- TCP的状态 (SYN, FIN, ACK, PSH, RST, URG)