[CC-CHANOQ]Chef and odd queries
题目大意:
给定$n(10^5)$个线段$[l_i,r_i](1\leq l_i,r_i\leq n)$,有$q(q\leq10^5)$组询问,每次给出$m_i(\sum m_i\leq n)$个点$x_{i,j}(1\leq x_{i,j}\leq n)$,问这些线段中有多少个线段覆盖了这些点中的奇数个点。
思路:
$q$比较小时,只需要对于每个位置$i$,处理位置$1\sim i$的点数前缀和。然后即可$O(1)$判断每个线段覆盖的点数的奇偶性。单笔询问时间复杂度$O(n+m)$。
由于$\sum m_i$有限制,所以当$q$比较大时,$m_i$就不会很大。可以用主席树记录对于$1\sim i$之间的左端点,每个区间内的右端点有多少。询问时对$x_{i,j}$排序,$O(m^2)$枚举线段覆盖了哪些点,用主席树求出符合条件的线段数即可。时间复杂度$O(m^2\log n)$。
因此对于每次询问不同的$m_i$,令较大的$m_i$执行$O(n+m)$的算法,令较小的$m_i$执行$O(m^2\log n)$的算法即可。
#include<cstdio> #include<cctype> #include<algorithm> inline int getint() { register char ch; while(!isdigit(ch=getchar())); register int x=ch^'0'; while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); return x; } const int N=1e5+1,M=1e5+2,logN=18; int p[M],cnt ; std::pair<int,int> seg ; class FotileTree { private: struct Node { int sum,left,right,vis; }; Node node[N*logN]; int sz,new_node(const int &p,const int &id) { node[++sz]=node[p]; node[sz].vis=id; return sz; } public: int root ; void modify(int &p,const int &b,const int &e,const int &x,const int &id) { if(node[p].vis!=id) p=new_node(p,id); node[p].sum++; if(b==e) return; const int mid=(b+e)>>1; if(x<=mid) modify(node[p].left,b,mid,x,id); if(x>mid) modify(node[p].right,mid+1,e,x,id); } int query(const int &p,const int &q,const int &b,const int &e,const int &l,const int &r) const { if(b==l&&e==r) return node[q].sum-node[p].sum; const int mid=(b+e)>>1; int ret=0; if(l<=mid) ret+=query(node[p].left,node[q].left,b,mid,l,std::min(mid,r)); if(r>mid) ret+=query(node[p].right,node[q].right,mid+1,e,std::max(mid+1,l),r); return ret; } void reset() { sz=0; } }; FotileTree t; int main() { for(register int T=getint();T;T--) { t.reset(); const int n=getint(); for(register int i=1;i<=n;i++) { const int l=getint(),r=getint(); seg[i]=std::make_pair(l,r); } std::sort(&seg[1],&seg +1); for(register int i=1,j=1;i<=n;i++) { t.root[i]=t.root[i-1]; for(;j<=n&&seg[j].first==i;j++) { t.modify(t.root[i],1,n,seg[j].second,i); } } for(register int i=getint();i;i--) { const int m=getint(); for(register int i=1;i<=m;i++) p[i]=getint(); int ans=0; if(m<=50) { p[m+1]=n+1; std::sort(&p[1],&p[m]+1); for(register int i=1;i<=m;i++) { if(p[i]==p[i-1]) continue; for(register int j=i;j<=m;j+=2) { if(p[j]==p[j+1]) continue; ans+=t.query(t.root[p[i-1]],t.root[p[i]],1,n,p[j],p[j+1]-1); } } } else { for(register int i=1;i<=n;i++) cnt[i]=0; for(register int i=1;i<=m;i++) cnt[p[i]]++; for(register int i=1;i<=n;i++) cnt[i]+=cnt[i-1]; for(register int i=1;i<=n;i++) { ans+=(cnt[seg[i].second]-cnt[seg[i].first-1])&1; } } printf("%d\n",ans); } } return 0; }
- [CC]Chef and Graph Queries
- codechef Tree and Queries Solved
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries
- 【欧拉筛+主席树】CodeChef PRMQ Chef and Prime Queries
- [CC-XXOR]Chef and Easy Problem
- [CC-FNCS]Chef and Churu
- [CodeChef - GERALD07 ] Chef and Graph Queries
- 【Codechef】【Chef and Graph Queries】Lct 可持久化线段树
- [CC]Chef and Churu
- CodeChef:Chef and Subarray Queries(线段树)
- CodeChef JUNE17 - Chef and Prime Queries
- CC DEC.17 Chef And Easy Xor Queries 分块+懒标记
- [CC-CHEFINV]Chef and Swaps
- [点分树] Codechef December Challenge 2017. Chef, Leonardo And Queries
- CodeChef Mahesh and his lost array
- Chef and Prime Divisors Problem code: CHAPD (GCD问题)
- php非缓冲查询数据库三种mysqli,pdo,mysql方式(Bufferedand Unbuffered queries)
- #373 Partition Array by Odd and Even
- cocos2d 中 CCNode and CCAction
- CC And MC Introduce