【CF】Sereja and Arcs
时间:2020-05-29
本文章向大家介绍【CF】Sereja and Arcs,主要包括【CF】Sereja and Arcs使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
#include <bits/stdc++.h> #define llong long long using namespace std; const int N = 1e5; const int P = 1e9+7; const llong INV2 = 5e8+4; int nxt[N+3]; int lstpos[N+3]; int a[N+3]; int num[N+3]; int cnum[N+3]; llong tmp0[N+3],tmp1[N+3],tmp2[N+3]; vector<int> clrpos[N+3]; int n,m,B; llong ans1,ans2a,ans2b,ans2c,ans0,ans; llong C2(llong x) {return x*(x-1ll)/2ll%P;} llong update(llong &x,llong y) {x = (x+y)%P;} struct BITree { llong tr[N+3]; int siz; void addval(int lrb,llong val) { while(lrb<=siz) { update(tr[lrb],val); lrb += (lrb&(-lrb)); } } llong querysum(llong rb) { llong ret = 0ll; while(rb) { update(ret,tr[rb]); rb -= (rb&(-rb)); } return ret; } void clear() { for(int i=0; i<=siz; i++) tr[i] = 0ll; } } bit1,bit2; void getans0() { llong cur = 0ll; for(int i=1; i<=m; i++) { llong tmp = C2(num[i]); update(ans0,cur*tmp%P); update(cur,tmp); } } void getans1() { llong tmp = 0ll; for(int i=1; i<=n; i++) { update(ans1,(tmp-C2(cnum[a[i]]))*(num[a[i]]-cnum[a[i]]-1)); update(tmp,(llong)cnum[a[i]]); cnum[a[i]]++; } } void getans2a() { bit1.siz = n; bit1.clear(); llong cur = 0ll; for(int i=1; i<=n; i++) { if(num[a[i]]<=B) { int tnum = 0; for(int j=nxt[i]; j; j=nxt[j]) { llong tmp = cur-bit1.querysum(j)-C2(tnum)+P+P; update(ans2a,tmp); tnum++; } for(int j=nxt[i]; j; j=nxt[j]) { cur++; bit1.addval(j,1); } } } } void getans2b() { for(int i=1; i<=m; i++) { if(num[i]>B) { tmp1[0] = 0ll; for(int j=1; j<=n; j++) tmp1[j] = tmp1[j-1]+(a[j]==i?1:0); for(int j=1; j<=m; j++) { if(num[j]<=B) { llong cur = 0ll; for(int k=0; k<clrpos[j].size(); k++) { int rb = clrpos[j][k]; llong tmp = (num[i]-tmp1[rb])*cur%P; update(ans2b,tmp); update(cur,tmp1[rb]); } } } } } } void getans2c() { for(int i=1; i<=m; i++) { if(num[i]>B) { tmp1[0] = 0; for(int j=1; j<=n; j++) tmp1[j] = tmp1[j-1]+(a[j]==i?1:0); for(int j=1; j<=m; j++) { if(i==j) continue; llong cur1 = 0ll,cur2 = 0ll; for(int k=0; k<clrpos[j].size(); k++) { int ra = clrpos[j][k]; llong tmp = tmp1[ra]*tmp1[ra]%P*k%P; update(ans2c,tmp); tmp = tmp1[ra]*(-2ll*cur1-k)%P+P; update(ans2c,tmp); tmp = cur2+cur1+P; update(ans2c,tmp); update(cur2,tmp1[ra]*tmp1[ra]); update(cur1,tmp1[ra]); } } } } ans2c = ans2c*INV2%P; } int main() { scanf("%d",&n); B = sqrt(n)/2; for(int i=1; i<=n; i++) scanf("%d",&a[i]),num[a[i]]++,m = max(m,a[i]),clrpos[a[i]].push_back(i); for(int i=1; i<=n; i++) { nxt[i] = lstpos[a[i]]; lstpos[a[i]] = i; } getans0(); getans1(); getans2a(); getans2b(); getans2c(); ans = ((ans0-ans1-ans2a-ans2b-ans2c)%P+P)%P; printf("%lld\n",ans); return 0; }
原文地址:https://www.cnblogs.com/xyj1/p/12989189.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 计算机网络--概论
- 因式分解(计蒜网)
- 区间合并(计蒜网)
- AtCoder Beginner Contest 161 A~~F
- 试题 算法训练 猴子吃包子
- 蓝桥杯 试题 基础练习 字符串对比
- 蓝桥杯 试题 基础练习 矩阵乘法
- 蓝桥杯 试题 基础练习 矩形面积交
- 蓝桥杯 试题 基础练习 完美的代价(详细c++)
- 牛客小白月赛23 部分题解
- AtCoder Beginner Contest 159 A~~D
- 最大连续子序列和(最大子数组和)四种最详细的解法
- 玩转 Linux 环境下日期的语法
- dubbo学习之事件通知实践
- Panasonic Programming Contest 2020 A ~~C