[计数 补集转换][阈值] Codechef SEAARC.Sereja and Arcs
2017-08-15 15:45
537 查看
传送门
%%%度神
很强的计数题
题目就是求形如ABAB的个数,发现这个很难求,补集转换一下,答案就是总数减去AABB和ABBA的个数
求总数很简单,就是
∏i=1n(ai2)
ai是第i中颜色个数
AABB的个数可以枚举p,然后用颜色的前后缀和求出来。
重点就是求ABBA了
直接求还是不好求,可以设一个阈值 S
Big为个数S的颜色的集合,Small为个数小于等于S的颜色集合。
那么就有四种情况:
A∈Big,B∈Big
A∈Big,B∈Small
A∈Small,B∈Big
A∈Small,B∈Small
分类讨论
A∈Small,B∈Small
这个子问题是小颜色包含小颜色,这个子问题就是典型的二维数点,可以证明∏i∈X(ai2)是O(nS)级别的,也就是这些颜色的数对和在nS以内,那么就用离线的求二维数点的方案就可以了。复杂度加个树状数组的log,就是O(nSlogn)
A∈Big,B∈Small
大颜色包含小颜色,枚举每种小颜色x和大颜色y,枚举左端点,右端点可以求出答案∑i=2ax∑j=1i−1prey,j×(ay−prey,i)∑i=2ax(ay−prey,i)∑j=1i−1prey,j维护一下∑i−1j=1prey,j,就不需要枚举右端点了,整个复杂度就是O(n2S)
A∈Small,B∈Big和A∈Small,B∈Big
这两类情况的解法一样,枚举A的左端点和右端点,枚举B的种类,答案是∑i=2aA∑j=1i−1(preB,i−preB,j2)展开可以得到12∑i=2aA(pre2B,i×(i−1)−2×preB,i∑j=1i−1preB,j+∑j=1i−1pre2B,j+∑j=1i−1preB,j+preB,i×(i−1))同样维护∑i−1j=1preB,j,∑i−1j=1pre2B,j就可以不用枚举右端点,复杂度就是O(n2S)
这样就可以了理论上S取nlogn−−−−√可以达到最优复杂度O(bnlogn−−−−−√),但是树状数组的常数贼小,而O(n2S)部分常数很大,所以取S=n√跑的最快。
打了一个晚上结果不小心关了电脑,代码就不见了…
第二天10分钟又打了一遍…
%%%度神
很强的计数题
题目就是求形如ABAB的个数,发现这个很难求,补集转换一下,答案就是总数减去AABB和ABBA的个数
求总数很简单,就是
∏i=1n(ai2)
ai是第i中颜色个数
AABB的个数可以枚举p,然后用颜色的前后缀和求出来。
重点就是求ABBA了
直接求还是不好求,可以设一个阈值 S
Big为个数S的颜色的集合,Small为个数小于等于S的颜色集合。
那么就有四种情况:
A∈Big,B∈Big
A∈Big,B∈Small
A∈Small,B∈Big
A∈Small,B∈Small
分类讨论
A∈Small,B∈Small
这个子问题是小颜色包含小颜色,这个子问题就是典型的二维数点,可以证明∏i∈X(ai2)是O(nS)级别的,也就是这些颜色的数对和在nS以内,那么就用离线的求二维数点的方案就可以了。复杂度加个树状数组的log,就是O(nSlogn)
A∈Big,B∈Small
大颜色包含小颜色,枚举每种小颜色x和大颜色y,枚举左端点,右端点可以求出答案∑i=2ax∑j=1i−1prey,j×(ay−prey,i)∑i=2ax(ay−prey,i)∑j=1i−1prey,j维护一下∑i−1j=1prey,j,就不需要枚举右端点了,整个复杂度就是O(n2S)
A∈Small,B∈Big和A∈Small,B∈Big
这两类情况的解法一样,枚举A的左端点和右端点,枚举B的种类,答案是∑i=2aA∑j=1i−1(preB,i−preB,j2)展开可以得到12∑i=2aA(pre2B,i×(i−1)−2×preB,i∑j=1i−1preB,j+∑j=1i−1pre2B,j+∑j=1i−1preB,j+preB,i×(i−1))同样维护∑i−1j=1preB,j,∑i−1j=1pre2B,j就可以不用枚举右端点,复杂度就是O(n2S)
这样就可以了理论上S取nlogn−−−−√可以达到最优复杂度O(bnlogn−−−−−√),但是树状数组的常数贼小,而O(n2S)部分常数很大,所以取S=n√跑的最快。
打了一个晚上结果不小心关了电脑,代码就不见了…
第二天10分钟又打了一遍…
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <cstring> #include <string> using namespace std; const int N=100010,M=330,P=1e9+7,inv2=P+1>>1; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void rea(int &x){ char c=nc(); x=0; for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); } inline void add(int &x,int y){ if((x+=y)>=P) x-=P; } int n,S,ans,a ,pre ,lst ,Size ,bit ; int pr[M] ,p [M],q [M],p2 [M]; vector<int> c ,bg; inline int C(int x){ return 1LL*x*(x-1)/2%P; } inline int Query(int l,int r){ int ret=0; for(;l<=n;l+=l&-l) ret+=bit[l]; for(r++;r<=n;r+=r&-r) ret-=bit[r]; return ret; } inline void Add(int x){ for(;x;x-=x&-x) bit[x]++; } int main(){ freopen("arcs.in","r",stdin); freopen("arcs.out","w",stdout); rea(n); S=sqrt(n); for(int i=1;i<=n;i++) rea(a[i]),c[a[i]].push_back(i); for(int i=1;i<=n;i++) pre[i]=lst[a[i]],lst[a[i]]=i; int cur=0; for(int i=1;i<=100000;i++){ if(c[i].size()>S) bg.push_back(i); add(ans,1LL*cur*C(c[i].size())%P),add(cur,C(c[i].size())); } for(int i=1;i<=n;i++){ add(cur,(P-(c[a[i]].size()-Size[a[i]]-1))%P); add(ans,P-1LL*Size[a[i]]*(cur+P-C(c[a[i]].size()-Size[a[i]]-1))%P); Size[a[i]]++; } memset(Size,0,sizeof(Size)); for(int i=1;i<=n;i++){ for(int j=0;j<bg.size();j++) pr[j][i]=pr[j][i-1]+(a[i]==bg[j]); } for(int i=1;i<=n;i++){ if(c[a[i]].size()<=S){ for(int j=0;c[a[i]][j]<i;j++) add(ans,(P-Query(c[a[i]][j]+1,i)+C(Size[a[i]]-j-1))%P),Add(c[a[i]][j]); for(int j=0;j<bg.size();j++){ if(bg[j]==a[i]) continue; q[i][j]=(q[pre[i]][j]+pr[j][pre[i]])%P; add(ans,P-1LL*(c[bg[j]].size()-Size[bg[j]])*q[i][j]%P); } } for(int j=0;j<bg.size();j++){ if(bg[j]==a[i]) continue; p[i][j]=(p[pre[i]][j]+pr[j][pre[i]])%P; p2[i][j]=(1LL*pr[j][pre[i]]*pr[j][pre[i]]+p2[pre[i]][j])%P; add(ans,P-1LL*inv2*((1LL*Size[a[i]]*pr[j][i]%P*pr[j][i]%P+P-2LL*pr[j][i]*p[i][j]%P+p2[i][j]+p[i][j]+P-1LL*Size[a[i]]*pr[j][i]%P)%P)%P); } Size[a[i]]++; } printf("%d\n",ans); return 0; }
相关文章推荐
- CodeChef SEAVOTE Sereja and Votes
- codechef January Challenge 2014 Sereja and Graph
- CodeChef Sereja and Game [DP 概率 博弈论]
- Codechef June Challenge 2014 #Sereja and Arcs -- 容斥 + 阈值 + 树状数组
- ●CodeChef Sereja and Game
- CodeChef Sereja and LCM(矩阵快速幂)
- CodeChef Sereja and GCD
- Convertion of grey code and binary 格雷码和二进制数之间的转换
- codechef Chef and The Right Triangles 题解
- codechef May Challenge 2016 CHSC: Che and ig Soccer dfs处理
- [DP] Codechef .Chef And Fibonacci Array
- Codechef2015 May - Chef and Strings (后缀自动机)
- 【前缀和 && 思维转换】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)Molly's Chemicals
- CodeChef Chef and Churu Problem
- CodeChef STFM - Chef and Strange Formula (康托展开)
- CodeChef Chef and Strange Operations
- codechef Jewels and Stones 题解
- CodeChef:Company and Club Hierarchies(树形dp & 技巧)
- CodeChef Cards, bags and coins [DP 泛型背包]
- CodeChef November Lunchtime 2013 Lucy and the Number Game(简单题)