题目链接:点击查看

题目大意:给出一个长度为 n 的数列 a ,现在规定 a 中的一段区间 [ l , r ],如果其中每个数字要么出现 0 次要么出现恰好 3 次,就规定这是个好区间,问共有多少个好区间

题目分析:可以枚举其中一个端点,然后计算另一个端点的贡献,我使用的是顺序枚举右端点来求出左端点的可行区间,先设 last[ a[ i ] ][ j ] 代表的是,到了第 i 个位置为止,前面第 j 个 a[ i ] 的位置,显然 last[ a[ i ] ][ 0 ] = i ,这样的话不难看出只有 last[ a[ i ] ][ 3 ] + 1 ~ last[ a[ i ] ][ 2 ] 这段区间是符合 a[ i ] 恰好出现三次的这个限制,称之为合法区间,其余位置都称之为非法区间,换句话说,对于第 i 个位置而言,只有在合法区间内的数才可以当右端点为 i 时作为左端点与其匹配,对于每个右端点 i 都会有一段相应的左端点区间,现在我们需要求出所有右端点的合法区间的交集,才能作为当前右端点的可行区间,举个很简单的例子,1 2 2 1 1 这个长度为 5 的数列,现在枚举的右端点是 a[ 5 ] ,也就是最后的那个 1 ,与其对应的可行区间是第一个位置 a[ 1 ] ,但是如果第一个位置作为左端点与其匹配的话,会导致 a[ 2 ] 和 a[ 3 ] 的这两个位置的 2 不满足条件了,所以对于每个位置的左端点,必须要选择前面所有位置可行区间的交集才行

关于每次更新每个位置的合法与非法区间,可以类似于滑动窗口一样滑过去,简单画个图表示一下,下图中绿色的区间是需要实时维护的,蓝色区间是上一次维护的,红色区间是本次需要维护的

这样我们就用线段树来维护一下区间的覆盖问题,合法区间不予以覆盖,非法区间予以覆盖,这样最后答案就是所有没被覆盖到的位置了,关于区间覆盖问题直接用线段树的标记永久化维护即可

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=5e5+100;int last[N][5];//last[i][j]:第i个位置前面的第j个a[i]的位置 struct Node
{int l,r;int sum,lazy;
}tree[N<<2];void pushup(int k)
{if(tree[k].lazy)tree[k].sum=0;else if(tree[k].l==tree[k].r)tree[k].sum=1;elsetree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;tree[k].sum=tree[k].lazy=0;if(l==r)return;int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}void update(int k,int l,int r,int val)
{if(tree[k].r<l||tree[k].l>r)return;if(tree[k].l>=l&&tree[k].r<=r){tree[k].lazy+=val;pushup(k);return;}update(k<<1,l,r,val);update(k<<1|1,l,r,val);pushup(k);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int n;scanf("%d",&n);build(1,1,n);LL ans=0;for(int i=1;i<=n;i++){int x;scanf("%d",&x);for(int j=4;j>0;j--)last[x][j]=last[x][j-1];last[x][0]=i;update(1,i,i,0);//更新第i个位置这条链上的值 update(1,last[x][1]+1,last[x][0],1);if(last[x][3]+1<=last[x][2])update(1,last[x][3]+1,last[x][2],-1);if(last[x][4]+1<=last[x][3])update(1,last[x][4]+1,last[x][3],1);ans+=tree[1].sum;}printf("%lld\n",ans);return 0;
}

CodeForces - 1418G Three Occurrences(线段树-标记永久化)相关推荐

  1. 模板:线段树标记永久化

    为了那不可知的询问永远坚守于此 解析 众所周知线段树的区间修改是需要打懒标记的 多数时候,这个标记在询问子区间时需要下传 而标记永久化,就是指不下传懒标记的一种操作 在某些时候标记不便下传时有所应用 ...

  2. [线段树 标记永久化 单调队列] BZOJ 1171 大sz的游戏 BZOJ 2892 强袭作战

    很好的题解:http://blog.sina.com.cn/s/blog_76f6777d0101dizp.html "考虑裸的n^2暴力dp. dp[i]=min(dp[j])+1 ( d ...

  3. 19.CF803G Periodic RMQ Problem 线段树+分块+线段树标记

    19.CF803G Periodic RMQ Problem 线段树+分块+线段树标记 个人Limitの线段树题单题解主目录:Limitの线段树题单 题解目录_HeartFireY的博客-CSDN博客 ...

  4. 2021牛客多校7 - xay loves trees(dfs序+主席树-标记永久化)

    题目链接:点击查看 题目大意:给出两棵以点 111 为根节点的有根树,现在要求满足条件的最大集合: 在第一棵树中,集合内的任意两个点都必须满足祖先关系,即 uuu 是 vvv 的祖先或 vvv 是 u ...

  5. Codeforces 997E Good Subsegments (线段树)

    题目链接 https://codeforces.com/contest/997/problem/E 题解 经典题,鸽了 159 天终于看明白题解了.. 考虑一个区间是连续的等价于这个区间内的 \((\ ...

  6. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  7. CodeForces - 1539F Strange Array(线段树区间合并)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,规定位置 iii 的贡献是:设 x=a[i]x=a[i]x=a[i],选择一个包含 iii 的区间 [l,r][l,r][l,r],将其中 ...

  8. CodeForces - 1430E String Reversal(线段树+模拟)

    题目链接:点击查看 题目大意:给出一个字符串 sss ,令其反转的串为 ttt ,每次操作可以将 ttt 中的两个相邻位置的字符交换,问最少需要进行多少次操作才能使得 ttt 变成 sss 题目分析: ...

  9. [HNOI2015]开店(树剖+主席树+标记永久化)

    听说正解点分树?我不会就对了 此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和 不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower ...

最新文章

  1. 现代神经网络要这么用才能创造智能
  2. CommonsMultipartFile 转为 File 类型
  3. Linux 命令 —— scp linux之间复制文件和目录
  4. Net编程 详解DataTable用法【转】
  5. Keras之DNN:基于Keras(sigmoid+binary_crossentropy+predict_proba)利用DNN实现分类预测概率——DIY二分类数据集预测新数据点
  6. @RequestParam与@PathVariable的区别
  7. Java面试常考的面试题整理
  8. LwIP应用开发笔记之五:LwIP无操作系统TCP服务器
  9. python 并列条形图_python – 如何绘制具有相同X坐标并排的条形图
  10. WAF自动化Fuzz工具-WAFNinja(绕WAF、绕过WAF)
  11. 硬盘变成脱机状态(由于管理员设置的策略,该磁盘处于脱机状态)
  12. 超全地牢场景unity3d模型素材网站整理
  13. 如何理解边沿触发器和脉冲触发器?
  14. 安卓开发 监听虚拟按键_Android 虚拟按键适配动态调整布局的方法
  15. java tongpaiyu danliantiao_Java Pinyin.cou4方法代碼示例
  16. 微场景:移动互联时代的营销革命
  17. 统计物理α和β方法体系介绍
  18. Resource体系
  19. Excel-VBA常用对象(Application、Workbook、Worksheet、Range)
  20. 高速刹车失灵,特斯拉回应女子坐车顶维权

热门文章

  1. 激活函数:sigmoid、Tanh、ReLU
  2. MySQL高级 - 日志 - 二进制日志(statement)
  3. SpringBootApplication注解
  4. hystrix是什么?
  5. NioEventLoop 的实例化过程
  6. 基于Xml 的IOC 容器-开始读取配置内容
  7. Redis中的Sentinel 连接使用
  8. xml方式实现aop-切点表达式的写法
  9. 为什么需要用户自定义类加载器及具体实现
  10. PageHelper概述与基本使用步骤介绍