题链:

http://codeforces.com/problemset/problem/549/F
题解:

分治,链表。
考虑对于一个区间[L,R],其最大值在p位置,
那么答案的贡献就可以分为3部分:
1.[L,p-1]中合法的区间
2.[p+1,R]中合法的区间
3.[L,R]中经过p的合法区间。
前两个因为是相同子问题,可以递归解决。
考虑如何求出3.的答案。
令S[i]表示$\sum_{k=1}^{i}A[i]$(即前缀和)
显然对于一组(l,r)表示的区间[l,r],
当且仅当满足L<=l<=p且p<r<=R(或L<=l<p且p<=r<=R),
并且 S[r]-S[l-1]-A[p]≡0 (mod K)时,才是合法区间。


但是如果直接递归实现,复杂度高达O(N^2)
所以预处理出每个元素在哪个包含它的最大区间里是最大值。
可以用单调栈O(N)维护出。
然后对于每个元素以及刚刚得出来的区间去计算贡献。
同时在计算贡献时,采用的方法是:
枚举一边的元素,然后用形如Query(ql,qr,qv)的方式去询问另一边S[*]==qv的个数
至于枚举哪一边,就是哪边短就枚举哪一边,这样可以保证询问次数为nlogn次的。
然后考虑如何询问。
如果采用主席树,则需要把复杂度再乘上一个log的询问代价,总的复杂度为O(N logN logN)
或者把询问离线成差分形式,插入链表,最后扫描链表O(N logN)得出答案(链表元素有N logN个),总的复杂度为O(N logN)
比如说对于询问Query(l,r,v)拆成两个(v,sign)的形式,我们在链表l-1中加入(v,-1),在链表r中加入(v,1)
最后从i=0到N扫描一遍,首先cnt[S[i]]++,(cnt[x]表示前缀i中x这个值出现了多少次)
然后再扫描i的询问链表,把ans+=cnt[v]*sign即可。
最后的ans既是答案。

代码:

#include<bits/stdc++.h>
#define MAXN 300050
#define INF 0x3f3f3f3f
using namespace std;
int N,K,more;
int A[MAXN],S[MAXN],L[MAXN],R[MAXN];
struct LINK{
int lnt;
int nxt[MAXN*20],val[MAXN*20],sign[MAXN*20],head[MAXN];
LINK(){lnt=2;}
void Add(int u,int v,int s){
if(u<0) return;
val[lnt]=v; sign[lnt]=s; nxt[lnt]=head[u]; head[u]=lnt++;
}
void Query(int l,int r,int v){
Add(l-1,v,-1); Add(r,v,1);
}
long long Getans(){
long long ret=0;
static int cnt[1000050];
for(int i=0;i<=N;i++){
cnt[S[i]]++;
for(int j=head[i];j;j=nxt[j])
ret+=sign[j]*cnt[val[j]];
}
return ret;
}
}Q;
void prework(){
static int stk[MAXN],top;
A[0]=A[N+1]=INF;
stk[top=1]=0;
for(int i=1;i<=N;i++){
while(A[stk[top]]<=A[i]) top--;
L[i]=stk[top]+1; stk[++top]=i;
}
stk[top=1]=N+1;
for(int i=N;i>=1;i--){
while(A[stk[top]]<A[i]) top--;
R[i]=stk[top]-1; stk[++top]=i;
}
for(int i=1;i<=N;i++)
S[i]=(S[i-1]+A[i])%K;
}
void solve(){
int al,ar,qv,ql,qr,sign;
for(int i=1;i<=N;i++){
if(L[i]==R[i]) continue;
more++;
if(i-L[i]+1<=R[i]-i+1) al=L[i]-1,ar=i-1,ql=i,qr=R[i],sign=1;
else al=i,ar=R[i],ql=L[i]-1,qr=i-1,sign=-1;
for(int j=al;j<=ar;j++){
qv=(1ll*S[j]+sign*A[i]%K+K)%K;
Q.Query(ql,qr,qv);
}
}
}
int main(){
scanf("%d%d",&N,&K);
for(int i=1;i<=N;i++) scanf("%d",&A[i]);
prework();
solve();
long long ans=Q.Getans();
printf("%lld\n",ans-more);
return 0;
}

  

●CodeForces 549F Yura and Developers的更多相关文章

  1. codeforces 549F Yura and Developers(分治、启发式合并)

    codeforces 549F Yura and Developers 题意 给定一个数组,问有多少区间满足:去掉最大值之后,和是k的倍数. 题解 分治,对于一个区间,找出最大值之后,分成两个区间. ...

  2. Codeforces 549F Yura and Developers

    probelm 题意 给定一个序列和一个mod值,定义[l,r]合法当l到r的全部元素和减去当中的最大值的结果能够整除mod.问共同拥有多少区间合法. 思路 一開始想的分治. 对于一个[l,r]我们能 ...

  3. Looksery Cup 2015 F - Yura and Developers 单调栈+启发式合并

    F - Yura and Developers 第一次知道单调栈搞出来的区间也能启发式合并... 你把它想想成一个树的形式, 可以发现确实可以启发式合并. #include<bits/stdc+ ...

  4. 【Codeforces549F】Yura and Developers [单调栈][二分]

    Yura and Developers Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample Input 4 ...

  5. Codeforces刷题计划

    Codeforces刷题计划 已完成:-- / -- [Codeforces370E]370E - Summer Reading:构造:(给定某些数,在空白处填数,要求不下降,并且相邻差值<=1 ...

  6. CF数据结构练习

    1. CF 438D The Child and Sequence 大意: n元素序列, m个操作: 1,询问区间和. 2,区间对m取模. 3,单点修改 维护最大值, 取模时暴力对所有>m的数取 ...

  7. Looksery Cup 2015 Editorial

    下面是题解,做的不好.下一步的目标是rating涨到 1800,没打过几次cf A. Face Detection Author: Monyura One should iterate through ...

  8. Codeforces Round #Pi (Div. 2) B. Berland National Library set

    B. Berland National LibraryTime Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  9. Codeforces Beta Round #69 (Div. 1 Only) C. Beavermuncher-0xFF 树上贪心

    题目链接: http://codeforces.com/problemset/problem/77/C C. Beavermuncher-0xFF time limit per test:3 seco ...

随机推荐

  1. beta冲刺4

    昨天的问题: 我的社团数据库表项的处理,代码修改后结果无法显示. 帖子内容无法显示出来. 首页图像未替换 登陆整合没有完成 今天的完成: 服务器部署成功 页面背景修改.(已上传,未确认实装.) 任务截 ...

  2. 【Alpha版本】冲刺阶段 - Day1 - 启航

    Alpha 阶段成员分工及任务量 成员 分工 任务量(小时) 袁逸灏 完成app用户车辆,子弹发射,背景移动,暂停界面,音乐界面,音乐查找,音乐播放 25 刘伟康 项目进度把控.分配任务.组织会议.整 ...

  3. 团队作业9——事后分析(Beta版本)

    事后诸葛亮分析 1.         总结 团队合照   a. 项目管理之事后诸葛亮会 ·设想和目标 (1)我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 个人学习 ...

  4. spring mvc 整合Quartz

    Quartz是一个完全由java编写的开源作业调度框架.不要让作业调度这个术语吓着你.尽管Quartz框架整合了许多额外功能, 但就其简易形式看,你会发现它易用得简直让人受不了!Quartz整合在sp ...

  5. Raid5两块硬盘掉线可以恢复数据吗_raid数据恢复案例分享

    本案例中发生故障的存储类型是HP P2000,虚拟化平台为vmware exsi,共有10块硬盘组成raid5(硬盘容量为1t,其中6号盘是热备盘),由于某些故障导致阵列中两块硬盘亮黄灯掉线,硬盘无法 ...

  6. 07-TypeScript的For循环

    在传统的JavaScript中,关于循环,可以有两种方式,一种是forEach,一种是for. forEach的用法如下: var sarr=[1,2,3,4]; sarr.desc="he ...

  7. 再一次, 不要使用(include/require)_once

    本文地址: http://www.laruence.com/2012/09/12/2765.html 最近关于apc.include_once_override的去留, 我们做了几次讨论, 这个APC ...

  8. TortoiseGit安装与使用

    公司的源码是在码云上,平时进行项目源码管理和团队开发都会使用到GIT,花了一天时间才将Git搞明白,这是一个工具,我在这里就简单说一下,其安装使用方法,也是对自己学习的总结;本文章适合于刚接触GIT的 ...

  9. 原生Ajax用法——一个简单的实例

    Ajax全名(Asynchronous(异步) JavaScript and XML )是可以实现局部刷新的 在讲AJax之前我们先用简单的实例说一下同步和异步这个概念 /*异步的概念(就是当领导有一 ...

  10. Spring Security入门(3-2)Spring Security对接用户的权限系统

    源文链接,多谢作者的分享: http://www.360doc.com/content/14/0727/16/18637323_397445724.shtml 1.原生的spring-security ...