考虑计算每个位置的数作为最小值时有多少种情况

方便起见,以位置为第二关键字比较大小,这样就不会出现“相同的”数

可以方便地计算出以i位置为最小值的区间端点的可行位置:[A,i],[i,B]

这是我选的一个区间,那么另一个区间会有两种情况:在[A,B]的范围内或者不在

不妨只考虑另一个区间在i这个区间的右边的情况,设这另一个区间是[l,r]

这种时候第一个区间的左端点是在[A,i]随便选的

第一种情况:

  如果l<=B,那么r显然也<=B,所以i<=第一个区间的右端点<l<=r<=B,发现方案数只与[i,B]这个区间的长度有关,可以由公式算出,或者是提前预处理推出

第二种情况:

  如果l>B,我还要保证[l,r]内的所有数都大于a[i],这种情况和第一个区间绝对不相交,所以第一个区间的右端点也可以随便选。可以用树状数组维护左端点>x的可选的区间个数

那么我可以按照数字从大到小做,给每个位置维护一个并查集,表示从这个点可延伸出的最远的端点(在这个范围内的数都>=now)

这样,A和B也就顺便算出来了

 #include<bits/stdc++.h>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pa;
const int maxn=2e5+,P=1e9+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,l[maxn],r[maxn],a[maxn],ori[maxn];
int stk[maxn],sh,rnk[maxn],tr[][maxn];
pa tmp[maxn];
struct Node{
int f,l,r;
}nd[maxn];
vector<int> pos[maxn];
int ans,c3[maxn];
bool flag[maxn]; inline int lowbit(int x){return x&(-x);}
inline void add(int i,int x,int y){
for(;x<=N;x+=lowbit(x)) tr[i][x]+=y,tr[i][x]%=P;
}
inline int query(int i,int x){
int re=;for(;x;x-=lowbit(x)) re+=tr[i][x],re%=P;return re;
} inline int getf(int x){return x==nd[x].f?x:nd[x].f=getf(nd[x].f);} inline void change(int l,int r,int d){
int n=1ll*(r-l+)*(r-l+)/%P;
add(,l,d*n),add(,r,d*n);
} inline void uni(int x){
flag[x]=;nd[x].l=nd[x].r=x;
int a=,b=;
if(flag[x-]) a=getf(x-);
if(flag[x+]) b=getf(x+);
if(a){
nd[a].f=x;
change(nd[a].l,nd[a].r,-);
nd[x].l=nd[a].l;
}if(b){
nd[b].f=x;
change(nd[b].l,nd[b].r,-);
nd[x].r=nd[b].r;
}
change(nd[x].l,nd[x].r,);
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd();
c3[]=;
for(i=;i<=N;i++) c3[i]=(c3[i-]+1ll*i*(i-)/)%P;
for(i=;i<=N;i++) ori[i]=a[i]=rd(),tmp[i]=MP(a[i],i),r[i]=N,l[i]=;
sort(tmp+,tmp+N+);
for(i=;i<=N;i++)
a[i]=lower_bound(tmp+,tmp+N,MP(a[i],i))-tmp,pos[a[i]].push_back(i);
for(i=;i<=N;i++) nd[i].f=i; for(i=N;i;i--){
int x=tmp[i].second;
uni(x);
int f=getf(x),l=nd[f].l,r=nd[f].r;
ans+=1ll*(x-l+)*(c3[r-x+]+1ll*(r-x+)*(query(,N)-query(,r+))%P)%P*ori[x]%P,ans%=P;
ans+=1ll*(r-x+)*(c3[x-l+]+1ll*(x-l+)*query(,l-)%P)%P*ori[x]%P,ans%=P;
} printf("%d\n",(ans+P)%P);
return ;
}

noiac26 T1 (并查集)的更多相关文章

  1. NOIP2017 Day2 T1 奶酪(并查集)

    题目描述 现有一块大奶酪,它的高度为 hhh ,它的长度和宽度我们可以认为是无限大的,奶酪 中间有许多 半径相同 的球形空洞.我们可以在这块奶酪中建立空间坐标系,在坐标系中, 奶酪的下表面为z=0z ...

  2. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  3. HDU 1232 并查集/dfs

    原题: http://acm.hdu.edu.cn/showproblem.php?pid=1232 我的第一道并查集题目,刚刚学会,我是照着<啊哈算法>这本书学会的,感觉非常通俗易懂,另 ...

  4. 洛谷 P2661 信息传递 Label:并查集||强联通分量

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  5. 图论&数据结构——并查集

    Wikioi 4246 NOIP模拟赛Day2T1 奶牛的身高  题目描述 Description 奶牛们在FJ的养育下茁壮成长.这天,FJ给了奶牛Bessie一个任务,去看看每个奶牛场中若干只奶牛的 ...

  6. POJ 1456 Supermarket 区间问题并查集||贪心

    F - Supermarket Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  7. POJ 2492 并查集扩展(判断同性恋问题)

    G - A Bug's Life Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u S ...

  8. HDOJ 1272 并查集

    小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  9. HDOJ并查集题目 HDOJ 1213 HDOJ 1242

    Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. ...

随机推荐

  1. 自己实现数据结构系列三---Stack

    一.代码部分 1.定义接口 public interface Stack<E> { int getSize(); boolean isEmpty(); void push(E e); E ...

  2. vue组件内部引入远程js文件

    之所以要做这个是因为,在一个组件内部需要引入一个js文件来定位.如果放在index.html,这样每个组件都会有这个js.所以需要在组件内单独引入. 第一种操作 Dom引入js: export def ...

  3. 4 Past progressive VS simple past

    1 一般过去时用来谈论过去开始和结束的活动.过去进行时用来谈论过去正在进行或者发生的活动. Why were you at office so later yesterday? I was worki ...

  4. 通过 MySQL 存储原理来分析排序和锁(转)

    先抛出几个问题 为什么不建议使用订单号作为主键? 为什么要在需要排序的字段上加索引? for update 的记录不存在会导致锁住全表? redolog 和 binlog 有什么区别? MySQL 如 ...

  5. [转帖]Runtime, Engine, VM 的区别是什么?

    这就是个WiFi和WLAN关系的问题嘛.Runtime是指用于支持程序运行时的组件,它可以是个Engine和/或VM.VM是一种系统抽象,它提供代码执行所需的API环境.Engine是一种处理抽象,它 ...

  6. 20181114教学sql

    --精确查找:查询水表编号为30408的业主记录 ' --模糊查询:查询业主名称包含'刘'的业主记录 SELECT * FROM T_OWNERS WHERE NAME LIKE '%刘%' --AN ...

  7. spring初始化bean时执行某些方法完成特定的初始化操作

    在项目中经常会在容器启动时,完成特定的初始化操作,如资源文件的加载等. 一 实现的方式有三种: 1.使用@PostConstruct注解,该注解作用于void方法上 2.在配置文件中配置init-me ...

  8. 金蝶CLOUD与EAS的区别

    1.金蝶K/3 WISE主要面向单体制造企业(主要是离散制造企业):2.金蝶K/3 Cloud主要面向业务类型单一(即主营业务单一)的.注重供应链与生产业务协同的.中小型(二层集团??)集团性企业(主 ...

  9. 【转】Java基础——容器分类

    Java容器可以说是增强程序员编程能力的基本工具,本系列将带您深入理解容器类. 容器的用途 如果对象的数量与生命周期都是固定的,自然我们也就不需要很复杂的数据结构. 我们可以通过创建引用来持有对象,如 ...

  10. Hbase存储模式

    以key.value的结构存储数据;  (table,rowkey,family,colum,timestamp)构成数据的key,value存储数据