CodeChef---- February Challenge 2018----Chef and odd queries(复杂度分块计算)
链接 https://www.codechef.com/FEB18/problems/CHANOQ/
Chef and odd queries Problem Code: CHANOQ
Let's say that a segment [l, r] crosses a point x if l ≤ x ≤ r.
Chef wants you to answer Q queries. In each query, you are given a set of M distinct points X1, X2, ..., XM; you should compute the number of good segments [Li, Ri] among the given N segments. A segment is good if it crosses an odd number of points out of the given M points.
Input
- The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
- The first line of each test case contains a single integer N denoting the number of segments.
- The following N lines describe the segments. For each i, the i-th of these lines contains two space-separated integers Li and Ri.
- The next line contains a single integer Q denoting the number of queries.
- The following Q lines describe the queries. Each of these lines starts with an integer M — the number of points in this query, followed by M space-separated integers X1, X2, ..., XM.
Constraints
- 1 ≤ T ≤ 100
- 1 ≤ Q ≤ N ≤ 100,000
- sum of M for all queries ≤ N
- sum of N over all test cases ≤ 200,000
- 1 ≤ Xi ≤ N for each valid i
- all Xi in each query are distinct
- 1 ≤ Li ≤ Ri ≤ N for each valid i
Subtasks
Subtask #1 (10 points): N, Q ≤ 300
Subtask #2 (90 points): original constraints
Output
For each query, print a single line containing the number of good segments for that query.
Example
Input: 2
5
4 5
3 5
2 4
1 3
5 5
2
4 1 2 3 4
1 4
5
4 5
3 5
2 4
2 3
5 5
2
2 2 5
3 1 2 5 Output: 3
3
5
5
/////////////////////////////////////////////////
根据M的大小把询问区分开,M足够大的直接一个o(n)处理,M小的把询问离线了处理
离线后复杂度为d/x*x²logn(d为总点数,x为M小的询问的M值,logn来自树状数组)
贴个自己代码
#include <bits/stdc++.h>
#define mst(a,b) memset((a),(b), sizeof a)
#define lowbit(a) ((a)&(-a))
#define IOS ios::sync_with_stdio(0);cin.tie(0);
using namespace std;
typedef long long ll;
const int mod=1e9+;
const int maxn=1e5+;
int n;
int bit[maxn];
void update(int pos){
while(pos<=n){
++bit[pos];
pos+=lowbit(pos);
}
}
int get(int pos){
int ret=;
while(pos){
ret+=bit[pos];
pos-=lowbit(pos);
}
return ret;
}
vector<int>rr[maxn],uu[maxn];
int l[maxn],r[maxn];
int ss[maxn];
int blo;
bool vis[maxn];int ap[maxn];
int x[maxn],sum[maxn];
ll ans[maxn];
struct node{
int l,to,c;
node(int a,int b,int d){l=a;to=b;c=d;}
};
vector<node>kk[maxn];
int main(){
#ifdef local
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
blo=sqrt(n);
for(int i=;i<=n;++i)scanf("%d%d",&l[i],&r[i]); for(int i=;i<=n;++i)rr[i].clear(),uu[i].clear(),kk[i].clear(),ss[i]=; for(int i=;i<=n;++i)rr[r[i]].push_back(l[i]),++ss[l[i]],--ss[r[i]+]; for(int i=;i<=n;++i)ss[i]=ss[i-]+ss[i]; int q;scanf("%d",&q);
for(int id=;id<=q;++id){
int m;scanf("%d",&m);
for(int i=;i<=m;++i)scanf("%d",&x[i]);
if(m>=blo-){
for(int i=;i<=m;++i)vis[x[i]]=true;
for(int i=;i<=n;++i)sum[i]=sum[i-]+vis[i];
int tmp=;
for(int i=;i<=n;++i){
int g=sum[r[i]]-sum[l[i]-];
tmp+=(g%?:);
}
for(int i=;i<=m;++i)vis[x[i]]=false;
ans[id]=tmp;
}else{
sort(x+,x++m);
int tmp=;
for(int i=;i<=m;++i)tmp+=ss[x[i]];
ans[id]=tmp;
int cc=-;
for(int len=;len<m;++len){
for(int st=;st+len<=m;++st){
int le=x[st],ri=x[st+len];
kk[ri].push_back(node(le,id,cc));
}
cc=-cc;
}
}
}
for(int i=;i<=n;++i)bit[i]=;
for(int i=n;i>;--i){
for(int j=;j<rr[i].size();++j)update(rr[i][j]);
for(int j=;j<kk[i].size();++j){
node&ha=kk[i][j];
ans[ha.to]+=ha.c*get(ha.l);
}
}
for(int i=;i<=q;++i)printf("%lld\n",ans[i]);
}
return ;
}
系数的设置来自一个表格
|
被计算次数 |
系数 |
在计算中被包含的长度 |
||||||
|
1 |
2 |
3 |
4 |
5 |
6 |
|||
|
计算的长度 |
1 |
1 |
1 |
2 |
3 |
4 |
5 |
6 |
|
2 |
-2 |
1 |
2 |
3 |
4 |
5 |
||
|
3 |
2 |
1 |
2 |
3 |
4 |
|||
|
4 |
-2 |
1 |
2 |
3 |
||||
|
5 |
2 |
1 |
2 |
|||||
简单来说就是你算覆盖长度为1的实际上把覆盖长度更多的也算进去了,乘上系数后就只剩下奇数的长度了
区分点设置的也不是很好,可能数据不是很变态,0.几秒过了
放个zk的代码,zk orz,他的代码更容易理解一点(他说也可以用主席树在线查询,emm有道理)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <stack>
#include <set>
#include <queue>
#include <assert.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int N = 1e5 + ;
const int M = 3e5 + ;
const LL mod = 1e9 + ;
#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define SZ(X) (X.size())
vector<int>F[N];
vector<pii>L;
int ans[N];
int cover[N];
int n,q;
int solve(int x){
for(int i = ; i < F[x].size(); i++){
cover[F[x][i]]++;
}
for(int i = ; i <= n; i++){
cover[i] += cover[i - ];
}
int ret = ;
for(int i = ; i < L.size(); i++){
if((cover[L[i].Y] - cover[L[i].X - ]) & )ret++;
}
for(int i = ; i <= n; i++)cover[i] = ;
return ret;
}
struct Query{
int el,er;
int flag;
int id;
Query(){}
Query(int _el,int _er,int _flag,int _id){
el = _el;er = _er;flag = _flag;id = _id;
}
};
vector<Query>Q[N];
int tree[N];
void update(int o){
while(o <= n){
tree[o]++;
o += o & -o;
}
}
int sum(int l,int r){
l--;
int ret = ;
while(r){
ret += tree[r];
r -= r & -r;
}
while(l){
ret -= tree[l];
l -= l & -l;
}
return ret;
}
void solveQ(){
int l = ;
for(int ql = ; ql <= n; ql++){
while(l < n && L[l].X <= ql){
update(L[l].Y);
l++;
}
for(int j = ; j < Q[ql].size(); j++){
ans[Q[ql][j].id] += Q[ql][j].flag * sum(Q[ql][j].el,Q[ql][j].er);
}
}
for(int i = ; i <= n; i++)tree[i] = ;
}
int main() {
#ifdef local
freopen("input", "r", stdin);
#endif // local
ios::sync_with_stdio();
cin.tie();
int t;
cin>>t;
while(t--){
cin>>n;
for(int i = ,l,r; i < n; i++){
cin>>l>>r;
L.pb(mp(l,r));
}
sort(L.begin(),L.end());
cin>>q;
for(int i = ,xn,x; i < q; i++){
cin>>xn;
while(xn--){
cin>>x;
F[i].pb(x);
}
}
int split = sqrt((n + )/log2(n + ));
for(int i = ; i < q; i++){
if(F[i].size() > split){
ans[i] = solve(i);
}
else {
ans[i] = ;
sort(F[i].begin(),F[i].end());
for(int z = ; z < F[i].size(); z++){
for(int j = z; j < F[i].size(); j++){
if((j - z) & )continue;
int el = F[i][j];
int er = (j + == F[i].size() ? n : F[i][j + ] - );
int x1 = (z == ? : F[i][z - ]);
int x2 = F[i][z];
// cout<<x1 + 1<<" "<<x2<<" "<<el<<" "<<er<<endl;
Q[x1].pb(Query(el,er,-,i));
Q[x2].pb(Query(el,er,,i));
}
}
}
}
solveQ();
for(int i = ; i < q; i++){
cout<<ans[i]<<"\n";
}
cout<<flush;
L.clear();
for(int i = ; i <= n; i++)Q[i].clear();
for(int i = ; i < q; i++)F[i].clear();
}
}
CodeChef---- February Challenge 2018----Chef and odd queries(复杂度分块计算)的更多相关文章
- codechef February Challenge 2018 简要题解
比赛链接:https://www.codechef.com/FEB18,题面和提交记录是公开的,这里就不再贴了 Chef And His Characters 模拟题 Chef And The Pat ...
- Codechef August Challenge 2018 : Chef at the River
传送门 (要是没有tjm(Sakits)的帮忙,我还真不知道啥时候能做出来 结论是第一次带走尽可能少的动物,使未带走的动物不冲突,带走的这个数量就是最优解. 首先这个数量肯定是下界,更少的话连第一次都 ...
- CodeChef February Challenge 2018 Broken Clock (三角函数推导 + 矩阵快速幂)
题目链接 Broken Clock 中文题面链接 令$cos(xα) = f(x)$ 根据三角函数变换公式有 $f(x) = \frac{2d}{l} f(x-1) - f(x-2)$ 我们现在 ...
- CodeChef February Challenge 2018 Points Inside A Polygon (鸽笼原理)
题目链接 Points Inside A Polygon 题意 给定一个$n$个点的凸多边形,求出$[ \frac{n}{10}]\ $个凸多边形内的整点. 把$n$个点分成$4$类: 横坐标奇, ...
- 【线段树 泰勒展开】Codechef April Challenge 2018 Chef at the Food Fair
第一次写泰勒展开:本地和CC差距好大 题目大意 大厨住的城市里办了一场美食节.一条街上开设了$N$个摊位,编号为$1∼N$.这天开始时,第$i$个摊位的食物会导致食物中毒的概率是$P_i$.在这一天中 ...
- Codechef October Challenge 2018 游记
Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...
- Codechef September Challenge 2018 游记
Codechef September Challenge 2018 游记 Magician versus Chef 题目大意: 有一排\(n(n\le10^5)\)个格子,一开始硬币在第\(x\)个格 ...
- [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)
[BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries
https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...
随机推荐
- [luogu 3175] [HAOI2015]按位或(min-max容斥+高维前缀和)
[luogu 3175] [HAOI2015]按位或 题面 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行按位或运算.问期望多少秒后,你手上的数字变成2^n ...
- crm---本项目的权限控制模式
一:url权限: 最底层的权限控制,,缺点在与没有预判的机制,造成客户体验下降. 前提: 为controller中的每一个方法(即资源)定义一个资源(Resource)名称,,该 ...
- 383-基于kintex UltraScale XCKU040的双路QSFP+光纤PCIe 卡
一.板卡概述 本板卡系我司自主研发,基于Xilinx UltraScale Kintex系列FPGA XCKU040-FFVA1156-2-I架构,支持PCIE Gen3 x8模式的高速信号处理板卡 ...
- 013-zabbix trapper方式监控
zabbix获取数据时有时会出现超时,如果一些数据需要执行比较长的时间才能获取的话,那么zabbix会出现异常,考虑到这种情况,zabbix增加了Trapper功能,客户端自己提交数据给zabbix. ...
- 最简洁地说明常用的git指令(1)
前提条件,在github上面创建一个仓库,注册好git账号,下面开始 首先在项目文件夹下面,如果有安装git则邮件gitbash进入控制台.另一种方式是使用IDEA打开你要上传的工程,在里面的命令行下 ...
- Python核心技术与实战——十四|Python中装饰器的使用
我在以前的帖子里讲了装饰器的用法,这里我们来具体讲一讲Python中的装饰器,这里,我们从前面讲的函数,闭包为切入点,引出装饰器的概念.表达和基本使用方法.其次,我们结合一些实际工程中的例子,以便能再 ...
- ubuntu 设置apt-get 代理
1 添加apt-get 代理配置文件 sudo vi /etc/apt/apt.conf.d/proxy.conf 2 添加内容 Acquire::http::Proxy "http://w ...
- 修改 git log
修改最新的log git commit --amend git push -f #强制推送 修改历log git rebase -i HEAD~2 pick 1f639c0 222pick a8aef ...
- python变量与常量内容:
''' python变量与常量内容: ''' # 变量:定义世间万物变化的状态 ''' height 180 weight 140 age 18 tree_name yuyang ''' # prin ...
- 安装python3之后,yum用不了
使用centos 安装python3,并默认python3为python版本之后,用不了yum 原因是yum依赖于python2组件 解决方法: vi /usr/bin/yum 和 vi /usr/l ...