异色弧

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

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std; typedef long long s64;
const int ONE = ;
const int MOD = 1e9+; vector <int> q[ONE]; int n;
int A[ONE];
int cnt,Ans;
int Max,vis[ONE];
int Jc[ONE],inv[ONE]; struct power
{
int l,r;
}a[]; bool cmp(const power &a,const power &b)
{
if(a.r == b.r) return a.l > b.l;
return a.r < b.r;
} void Moit(int &a)
{
if(a<MOD) a+=MOD;
if(a>MOD) a-=MOD;
} int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} namespace D
{
int Quickpow(int a,int b)
{
int res=;
while(b)
{
if(b&) res=(s64)res*a%MOD;
a=(s64)a*a%MOD;
b>>=;
}
return res;
} void Deal_Jc(int k)
{
Jc[]=;
for(int i=;i<=k;i++) Jc[i] = (s64)Jc[i-]*i%MOD;
} void Deal_inv(int k)
{
inv[]=; inv[k] = Quickpow(Jc[k],MOD-);
for(int i=k-;i>=;i--) inv[i] = (s64)inv[i+]*(i+)%MOD;
} void pre(int k)
{
Deal_Jc(k); Deal_inv(k);
}
} int C(int n,int m)
{
if(n < m) return ;
return (s64)Jc[n]*inv[m]%MOD*inv[n-m]%MOD;
} namespace Bit
{
int C[ONE]; int lowbit(int x)
{
return x&-x;
} void Add(int R,int x)
{
for(int i=R;i<=n;i+=lowbit(i))
C[i]+=x, Moit(C[i]);
} int Query(int R)
{
int res=;
for(int i=R;i>=;i-=lowbit(i))
res+=C[i], Moit(res);
return res;
}
} int main()
{
n=get(); D::pre(n+);
for(int i=;i<=n;i++)
{
A[i]=get();
q[A[i]].push_back(i);
Max=max(Max,A[i]);
}
for(int k=;k<=Max;k++)
{
if(!q[k].size()) continue;
Ans-=C(q[k].size(),); Moit(Ans);
for(int i=;i< q[k].size();i++)
for(int j=i+;j< q[k].size();j++)
a[++cnt].l=q[k][i], a[cnt].r=q[k][j];
} sort(a+,a+cnt+,cmp);
for(int i=;i<=cnt;i++)
{
Ans += Bit::Query(a[i].l-);
Moit(Ans);
Bit::Add(a[i].l,), Bit::Add(a[i].r-,-);
} printf("%d",Ans);
}

【Foreign】异色弧 [树状数组]的更多相关文章

  1. BZOJ.4888.[TJOI2017]异或和(树状数组)

    BZOJ 洛谷 \(Description\) 求所有区间和的异或和. \(n\leq 10^5,\ \sum a_i\leq 10^6\). \(Solution\) 这样的题还是要先考虑按位做. ...

  2. Luogu3760 TJOI2017 异或和 树状数组

    传送门 题意:给出一个长度为$N$的非负整数序列,求其中所有连续区间的区间和的异或值.$N \leq 10^5$,所有元素之和$\leq 10^6$ 设序列的前缀和为$s_i$,特殊地,$s_0=0$ ...

  3. [BZOJ4888][TJOI2017]异或和(树状数组)

    题目描述 在加里敦中学的小明最近爱上了数学竞赛,很多数学竞赛的题都是与序列的连续和相关的.所以对于一个序列,求出它们所有的连续和来说,小明觉得十分的简单.但今天小明遇到了一个序列和的难题,这个题目不仅 ...

  4. P5057 [CQOI2006]简单题 前缀异或差分/树状数组

    好思路,好思路... 思路:前缀异或差分 提交:1次 题解:区间修改,单点查询,树状数组,如思路$qwq$ #include<cstdio> #include<iostream> ...

  5. 洛谷 P6225 [eJOI2019]异或橙子 (树状数组)

    题意:有\(n\)个数,起始值均为\(0\),进行\(q\)次操作,每次输入三个数,如果第一个数为\(1\),则将第\(i\)个数修改为\(j\),如果为\(2\),则求区间\([l,r]\)内的所有 ...

  6. [CSP-S模拟测试]:异或(树状数组+LCA)

    题目传送门(内部题21) 输入格式 第一行一个字符串$str$,表示数据类型.第二行一个正整数$k$,表示集合$K$的大小,保证$k>1$.接下来$k$行每行$k$个数,第$i$行第$j$个数表 ...

  7. 【树状数组】区间出现偶数次数的异或和(区间不同数的异或和)@ codeforce 703 D

    [树状数组]区间出现偶数次数的异或和(区间不同数的异或和)@ codeforce 703 D PROBLEM 题目描述 初始给定n个卡片拍成一排,其中第i个卡片上的数为x[i]. 有q个询问,每次询问 ...

  8. 【BZOJ4888】[TJOI2017]异或和(树状数组)

    [BZOJ4888][TJOI2017]异或和(树状数组) 题面 BZOJ 洛谷 题解 考虑每个位置上的答案,分类讨论这一位是否存在一,值域树状数组维护即可. #include<iostream ...

  9. BZOJ4888 [Tjoi2017]异或和 【树状数组】

    题目链接 BZOJ4888 题解 要求所有连续异或和,转化为任意两个前缀和相减 要求最后的异或和,转化为求每一位\(1\)的出现次数 所以我们只需要对每一个\(i\)快速求出\(sum[i] - su ...

随机推荐

  1. Java重写构造方法

    public class TestSuper { public static void main(String[] args) { new ChildClass("alex", 1 ...

  2. FPGA等占空比奇偶分频和半整数分频

    1. 偶数分频比较简单,如果分频系数是N(如果N是偶数,那么N/2是整数),那么在输入时钟的每隔N/2个周期时(计数器从0到N/2-1),改变输出时钟的电平即可得到50%固定占空比的时钟.需要的代码如 ...

  3. python基础——重访类型分类

    python基础--重访类型分类 对象根据分类来共享操作:例如,字符串.列表和元组都共享诸如合并.长度和索引等序列操作. 只有可变对象(列表.字典和集合)可以原处修改:我们不能原处修改数字,字符串.元 ...

  4. android activity状态保存

    一.被其他任务打断(来电话),再次打开希望保留数据 private String SAVE_INSTANCE_TAG = "ATWAL"; @Override protected ...

  5. Spring.Net在ASP.NET Mvc里使用的一个小例子

    就贴个小例子,就不注意格式了. 1.下载dll NuGet的下载地址:http://docs.nuget.org/docs/start-here/installing-nuget 在vs的NuGet里 ...

  6. 「个人训练」Copying Books(UVa714)

    好久不更新主要是怠惰了....还要加强训练. 题意分析与思路 注意到这样一句话: our goal is to minimize the maximum number of pages assigne ...

  7. Node.js的require()的工作原理

    大多数人都知道Node.js中require()函数做什么的,但是有多少人知道它的工作原理呢?我们每天使用它加载库包和模块,但是它的内部行为原理很神秘. 我们追寻Node模块系统的核心: module ...

  8. SpringBoot:工厂模式实现定时任务可配置

    pringBoot:工厂模式实现定时任务可配置 需要:使用springboot,实现定时任务可配置. 定时任务可在代码中写死,在配置文件中配置,这些都不能实现定时任务在服务器不重启的情况下可配置. 为 ...

  9. 并查集——poj1611(入门)

    传送门:The Suspects 并查集水题 #include <iostream> #include <cstdio> #include <algorithm> ...

  10. BZOJ1037 ZJOI2008生日聚会(动态规划)

    设f[i][j][x][y]为安排了i个男孩j个女孩,后缀最大男孩-女孩数为x,最大女孩-男孩数为y的方案数.转移显然. #include<iostream> #include<cs ...