hihocoder1236(北京网络赛J):scores 分块+bitset
2015-09-23 11:34
537 查看
北京网络赛的题- -。当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了
题意:
初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查询的五种能力值,输出有多少个人每种能力值都比查询的小
n和q都是50000,每种能力值最大也为50000
思路:
对于某一个大小的能力值,有哪些人的此项能力值比他小可以用一个50000的bitset表示。这样我们在查询的时候就可以拿到5个对应的bitset,对其进行and就可以得出最终的人数
这样每组询问的复杂度为5*n/32 总复杂度较高但勉强可以接受。
但是这样做有一点问题就是要开5*50000个大小为50000的bitset,显然这样会超内存。。于是想到将bitset分块,这样虽然询问时需要花费一定时间(sqrt)来找到5个bitset
但是显然这个时间是小于n/32的,所以并不会对总时间造成较大的影响,于是显然可行
注意一点就是分块的时候不仅要按照分数段分块,还要按照人数分块,否则如果某个分数段人数太多就gg了
代码:
View Code
题意:
初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查询的五种能力值,输出有多少个人每种能力值都比查询的小
n和q都是50000,每种能力值最大也为50000
思路:
对于某一个大小的能力值,有哪些人的此项能力值比他小可以用一个50000的bitset表示。这样我们在查询的时候就可以拿到5个对应的bitset,对其进行and就可以得出最终的人数
这样每组询问的复杂度为5*n/32 总复杂度较高但勉强可以接受。
但是这样做有一点问题就是要开5*50000个大小为50000的bitset,显然这样会超内存。。于是想到将bitset分块,这样虽然询问时需要花费一定时间(sqrt)来找到5个bitset
但是显然这个时间是小于n/32的,所以并不会对总时间造成较大的影响,于是显然可行
注意一点就是分块的时候不仅要按照分数段分块,还要按照人数分块,否则如果某个分数段人数太多就gg了
代码:
#include <bits/stdc++.h> using namespace std; bitset<50010>b[7][500]; bitset<50010>tmp; int n,m,q; int a[50010][7]; vector<int>v[7][50010]; bitset<50010>p[7]; int tt=10; int now[5]; vector<int>d[7]; int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0; i<5; i++) { d[i].clear(); for(int j=1; j<=m; j++) { v[i][j].clear(); } } for(int i=0;i<5;i++) { for(int j=1;j<=300;j++) { b[i][j].reset(); } } for(int i=0; i<n; i++) { for(int j=0; j<5; j++) { scanf("%d",a[i]+j); v[j][a[i][j]].push_back(i); } } int tm=0; for(int i=0; i<5; i++) { tm=0; tmp.reset(); b[i][0]=tmp; d[i].push_back(0); for(int j=0; j<=m; j++) { for(int to:v[i][j]) { tmp[to]=1; tm++; } if(tm>sqrt(n)||j-d[i][(int)d[i].size()-1]>sqrt(m)||j==m) { b[i][(int)d[i].size()]=tmp; d[i].push_back(j); tm=0; } } } scanf("%d",&q); int pre=0; tm=0; while(q--) { for(int i=0; i<5; i++) { scanf("%d",now+i); now[i]^=pre; } for(int i=0; i<5; i++) { int kk=upper_bound(d[i].begin(),d[i].end(),now[i])-d[i].begin(); kk--; p[i]=b[i][kk]; for(int j=d[i][kk]+1; j<=now[i]; j++) { for(int to:v[i][j]) { p[i][to]=1; } } //p&=tmp; } for(int i=1;i<5;i++) { p[0]&=p[i]; } int ans=p[0].count(); pre=ans; printf("%d\n",ans); } } return 0; }
View Code
相关文章推荐
- HTTP 错误 404.3 - Not Found(WCF+ASP.NET)
- XE8-indy10中TIdTCPConnection.Connected函数的源码
- 9.23 多线程学习 网络编程
- iOS学习---http协议
- TCP/IP 协议(三)
- HTTP请求的基本过程
- JavaScript学习总结(七)Ajax和Http状态字
- 【深度学习】卷积神经网络(Convolutional Neural Networks)
- 2015年下半年信管中高级网络面授直播课程(30课时)
- [iOS 多线程 & 网络 - 4.0] - AFN框架简单使用
- HttpPost,HttpGet,HttpPut,HttpDelete请求方式
- Httpclient对cookie的自动处理设置
- AFN框架使用
- http post请求
- HTTPS的七个误解
- OSI7层网络协议
- MD5登陆
- java http缓存
- java http缓存
- java http缓存