博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Foreign】异色弧 [树状数组]
阅读量:6006 次
发布时间:2019-06-20

本文共 3089 字,大约阅读时间需要 10 分钟。

  异色弧

Time Limit: 20 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  仅一行一个整数表示答案。

Sample Input

  8

  1 2 3 1 2 3 2 1

Sample Output

  8

HINT

  

Main idea

  给定若干个点,每个点有一个颜色,颜色一样的可以组成一个区间,询问有几个交。

Solution

  BearChild只会70分的做法,记录N表示区间个数,效率为O(Nlog(N))。这里介绍一下。

  我们基于将所有区间提取出来计算,可以用一个vector存一下记录相同颜色的,然后相同颜色的任意组合即可组成可行的区间。

  首先我们考虑容斥颜色不同的相交个数 = 不考虑颜色的总相交个数 - 颜色相同的相交个数。然后我们分段来解:

  1. 不考虑颜色的总相交个数:

    我们考虑带log的算法,先将所有区间按照右端点(细节:若相同则将左端点大的放在前面,保证不会算入答案)排序,然后顺序往后做,每次用树状数组在区间左端点+1区间(右端点-1)处-1(细节:右端点-1处是为了处理前一个的右端点=这一个的左端点情况),然后每次只要查询(左端点-1)的前缀和,显然就是在这个区间前和这个区间的交的个数。这样我们就可以计算出总相交个数了。

  2.颜色相同的相交个数:

    我们考虑如何计算颜色相同的相交个数,设a表示一个颜色的个数,显然个数就是:C(a,4)。也就是任意4个相同颜色点可以组成一个交。

  然后我们相减一下,就可以得到答案啦。注意一下细节。

Code

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 using namespace std; 9 10 typedef long long s64; 11 const int ONE = 100010; 12 const int MOD = 1e9+7; 13 14 vector
q[ONE]; 15 16 int n; 17 int A[ONE]; 18 int cnt,Ans; 19 int Max,vis[ONE]; 20 int Jc[ONE],inv[ONE]; 21 22 struct power 23 { 24 int l,r; 25 }a[20000001]; 26 27 bool cmp(const power &a,const power &b) 28 { 29 if(a.r == b.r) return a.l > b.l; 30 return a.r < b.r; 31 } 32 33 void Moit(int &a) 34 { 35 if(a
MOD) a-=MOD; 37 } 38 39 int get() 40 { 41 int res=1,Q=1; char c; 42 while( (c=getchar())<48 || c>57) 43 if(c=='-')Q=-1; 44 if(Q) res=c-48; 45 while((c=getchar())>=48 && c<=57) 46 res=res*10+c-48; 47 return res*Q; 48 } 49 50 namespace D 51 { 52 int Quickpow(int a,int b) 53 { 54 int res=1; 55 while(b) 56 { 57 if(b&1) res=(s64)res*a%MOD; 58 a=(s64)a*a%MOD; 59 b>>=1; 60 } 61 return res; 62 } 63 64 void Deal_Jc(int k) 65 { 66 Jc[0]=1; 67 for(int i=1;i<=k;i++) Jc[i] = (s64)Jc[i-1]*i%MOD; 68 } 69 70 void Deal_inv(int k) 71 { 72 inv[0]=1; inv[k] = Quickpow(Jc[k],MOD-2); 73 for(int i=k-1;i>=1;i--) inv[i] = (s64)inv[i+1]*(i+1)%MOD; 74 } 75 76 void pre(int k) 77 { 78 Deal_Jc(k); Deal_inv(k); 79 } 80 } 81 82 int C(int n,int m) 83 { 84 if(n < m) return 0; 85 return (s64)Jc[n]*inv[m]%MOD*inv[n-m]%MOD; 86 } 87 88 namespace Bit 89 { 90 int C[ONE]; 91 92 int lowbit(int x) 93 { 94 return x&-x; 95 } 96 97 void Add(int R,int x) 98 { 99 for(int i=R;i<=n;i+=lowbit(i))100 C[i]+=x, Moit(C[i]);101 }102 103 int Query(int R)104 {105 int res=0;106 for(int i=R;i>=1;i-=lowbit(i))107 res+=C[i], Moit(res);108 return res;109 }110 }111 112 int main()113 { 114 n=get(); D::pre(n+1);115 for(int i=1;i<=n;i++)116 {117 A[i]=get();118 q[A[i]].push_back(i);119 Max=max(Max,A[i]); 120 }121 for(int k=1;k<=Max;k++)122 {123 if(!q[k].size()) continue;124 Ans-=C(q[k].size(),4); Moit(Ans);125 for(int i=0;i< q[k].size();i++)126 for(int j=i+1;j< q[k].size();j++)127 a[++cnt].l=q[k][i], a[cnt].r=q[k][j];128 }129 130 sort(a+1,a+cnt+1,cmp);131 for(int i=1;i<=cnt;i++)132 {133 Ans += Bit::Query(a[i].l-1);134 Moit(Ans);135 Bit::Add(a[i].l,1), Bit::Add(a[i].r-1,-1);136 }137 138 printf("%d",Ans); 139 }
View Code

 

转载于:https://www.cnblogs.com/BearChild/p/6522789.html

你可能感兴趣的文章
[LintCode] 604. Design Compressed String Iterator
查看>>
微信小程序黑客马拉松即将开始,来做最酷的 Mini Program Creators!
查看>>
JavaScript基础---函数
查看>>
前端每日实战:120# 视频演示如何用纯 CSS 创作锡纸撕开的文字效果
查看>>
Laravel实用小功能
查看>>
matplotlib绑定到PyQt5(有菜单)
查看>>
利用Powershell和ceye.io实现Windows账户密码回传
查看>>
Windows 8.1 今年 1 月市场份额超 Vista
查看>>
《设计团队协作权威指南》—第1章1.5节总结
查看>>
Chair:支付宝前端团队推出的Node.js Web框架
查看>>
《Total Commander:万能文件管理器》——第3.8节.后续更新
查看>>
BSD vi/vim 命令大全(下)[转]
查看>>
css3中变形与动画(一)
查看>>
[XMove-自主设计的体感解决方案] 系统综述
查看>>
【LINUX学习】磁盘分割之建立primary和logical 分区
查看>>
【YUM】第三方yum源rpmforge
查看>>
IOS(CGGeometry)几何类方法总结
查看>>
才知道系列之GroupOn
查看>>
⑲云上场景:超级减肥王,基于OSS的高效存储实践
查看>>
linux kswapd浅析
查看>>