codeforces 387C George and Number
2014-02-25 13:44
302 查看
这道题目的意思是对于每个要删除的数字,向前或向后找到一块连续的数字,而它是其中最小的;
很容易看出对于所有要先删除的数字要从大到小删除;
然后对于每个要删除的字母,要找到比他小的,但是在原数列中又靠它最近的数字;
这样的话,很直观最多只能用lg n的复杂度来处理这个问题;
可以用二分查找,也可以用set来代替;
考虑到前面删除的一些数字不能计算进去,还要一个快速计算区间和的算法,用树状数组和线段树都可以;
不过看到tags,上面写着还可以用dsu(disjoint set union)并查集来做;
感觉挺神奇的,想到了之后再补上!
View Code
很容易看出对于所有要先删除的数字要从大到小删除;
然后对于每个要删除的字母,要找到比他小的,但是在原数列中又靠它最近的数字;
这样的话,很直观最多只能用lg n的复杂度来处理这个问题;
可以用二分查找,也可以用set来代替;
考虑到前面删除的一些数字不能计算进去,还要一个快速计算区间和的算法,用树状数组和线段树都可以;
不过看到tags,上面写着还可以用dsu(disjoint set union)并查集来做;
感觉挺神奇的,想到了之后再补上!
#include<cstdio> #include<iostream> #define maxn 1000006 using namespace std; int n,m; int pos[maxn]; bool can[maxn]; int size[maxn]; int f[maxn]; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } void dsu_union(int x,int y) { int a=find(x); int b=find(y); if(a==b)return; f[b]=a; size[a]+=size[b]; size[b]=0; } void interval_union(int p) { if(p>0&&!can[p-1]) dsu_union(p,p-1); if(p<n&&!can[p+1]) dsu_union(p,p+1); } int main() { int num,p; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&num); pos[num]=i; f[i]=i; } for(int i=1;i<=m;i++) { scanf("%d",&num); can[pos[num]]=1; } for(int i=1;i<=n;i++) if(!can[i]) interval_union(i); long long ans=0; for(int i=n;i>=1;i--) { p=pos[i]; num=find(p); size[num]++; if(!can[p]) ans+=size[num]; else { can[p]=0; interval_union(p); } } cout<<ans; }
View Code
相关文章推荐
- HDUOJ---1233还是畅通工程
- 比特币的三个视角
- 切勿暴饮暴食:春节
- 基于V4L2的视频驱动开发(1)
- 开发笔记之20140225
- UIWebView中视频点击链接直接全屏播放而不是点击一个播放按钮的实现方法
- php反射应用实例代码
- 无题诗我自己写的
- Linux下利用luvcview来进行图像识别-准备
- jquery 在指定位置弹出div框并实现从下向上展开效果
- Builder模式的误区:将复杂对象的构建进行封装,就是Builder模式了吗?
- 惊天发现,cocos2d居然有个开源的lua框架,作者怎么这么低调?
- oracle中的Round和Trunc:
- MFC 浮动提示框 CToolTipCtrl 控件
- 误读善泳者溺的古训,害人不浅_泳者无涤_新浪博客
- 如何从Eclipse中导入第三方库(并且是带有JNI的)到Android Studio开发工具中?
- 如何从SD卡中恢复你删除掉的照片
- 安装JBPM6运行环境(JBPM6学习之二)
- jquery 在指定位置弹出div框并实现DIV由下向上展开的效果
- daemon进程原理及实现(来源于网络,后整理)