hdu5714Helter Skelter
2016-07-23 17:06
417 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5741
题意:给定一个01交替的字符串s的压缩表示和m个询问。00110的压缩表示为"221"表示先2个0再2个1再1个0。然后给定m个询问每个询问a,b,问在原s串中是否存在一个区间[l,r]中恰好是0的个数为a,1的个数为b。
分析:这是个找规律的题,其实多分析下就行了,一些猜想虽然不好证但是正确性还是挺明显的。看xg的题解吧。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=1010; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const int MAX=2000000010; const ll INF=1ll<<55; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; struct node { int x,y; node() {} node(int x,int y):x(x),y(y) {} }f[N*N],g[N*N],d[N*N]; bool cmd1(node a,node b) { if (a.y!=b.y) return a.y<b.y; else return a.x>b.x; } bool cmd2(node a,node b) { if (a.x!=b.x) return a.x<b.x; else return a.y>b.y; } int a ; int getmi(int l,int r,int x) { if (x>f[r].x) return MAX; int mid=(l+r)>>1; while (l+1<r) if (f[mid].x<x) { l=mid;mid=(l+r)>>1; } else { r=mid;mid=(l+r)>>1; } return f[r].y; } int getmx(int l,int r,int x) { if (x>=g[r].x) return g[r].y; int mid=(l+r)>>1; while (l+1<r) if (g[mid].x<=x) { l=mid;mid=(l+r)>>1; } else { r=mid;mid=(l+r)>>1; } return g[l].y; } int main() { int i,j,k,n,m,t,mi,mx,numf,numg,zero,one; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (i=1;i<=n;i++) scanf("%d", &a[i]); numf=numg=0; for (i=1;i<=n;i+=2) { zero=one=0; for (j=i;j<=n;j++) if (j&1) { zero+=a[j];f[++numf]=node(zero,one); } else one+=a[j]; } for (i=2;i<=n;i+=2) { zero=one=0; for (j=i;j<=n;j++) if (j&1) zero+=a[j]; else { one+=a[j];g[++numg]=node(zero,one); } } sort(f+1,f+numf+1,cmd1); k=1;d[1]=node(-1,-1); for (i=1;i<=numf;i++) if (f[i].x>d[k].x&&f[i].y>d[k].y) d[++k]=f[i]; d[1].x=d[1].y=0;numf=k; for (i=1;i<=k;i++) f[i]=d[i]; sort(g+1,g+numg+1,cmd2); k=1;d[1]=node(-1,-1); for (i=1;i<=numg;i++) if (g[i].x>d[k].x&&g[i].y>d[k].y) d[++k]=g[i]; d[1].x=d[1].y=0;numg=k; for (i=1;i<=k;i++) g[i]=d[i]; while (m--) { scanf("%d%d", &zero, &one); mi=getmi(1,numf,zero); mx=getmx(2,numg,zero); if (mi<=one&&one<=mx) printf("1"); else printf("0"); } printf("\n"); } return 0; }
相关文章推荐
- Java高效编程建议
- 使用git遇到的问题
- 011-数字颠倒
- Yii2主题(Theme)用法详解
- 二维递增子序列
- POJ 3372 Candy Distribution
- 康托逆展开式
- 从内存理解c语言中变量的存储类型
- HDOJ 1789 Doing Homework again
- C/C++ 图像处理(11)------图像の仿射变换
- CodeForces 698A Vacations(贪心)
- zookeeper客户端四字符指令
- Tiny6410学习-windows/ubuntu 文件共享 Samba配置
- python矩阵和数组之间转换
- 利用元类编写简单的ORM框架
- 神秘西夏
- 页面中加入回到顶部按钮的实现方法
- 各进制转换
- 再回首-无符号大整数加法
- HTTPS工作原理