您的位置:首页 > 大数据 > 人工智能

2016 Multi-University Training Contest 2 H Helter Skelter (hdu5741) 【二分】

2016-07-24 10:44 871 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5741

题意:给你n个数字表示一个字符串s的压缩形式,再给你m个询问,询问是否存在一个区间是由a个0,b个1组成,是输出1,否输出0.

分析:如果我们确定了a的个数,那么b的个数就是一个区间,我们暴力将所有的可行(a,b),可以发现他们分布在一个封闭的二位平面上,我们可以找到这个二维平面的上界,下界(就是b的范围),二分a看b是否在这个区间内。xg题解

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 1010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int a[Mn];
int sum[Mn][2];
struct node {
int x,y;
node(){}
node(int x,int y):x(x),y(y){}
}up[Mn*Mn],down[Mn*Mn];
bool cmp1(node a,node b) {
if(a.y==b.y) return a.x>b.x;
return a.y<b.y;
}
bool cmp2(node a,node b) {
if(a.x==b.x) return a.y>b.y;
return a.x<b.x;
}
int getup(int l,int r,int x) {
while(l+1<r) {
int mid=(l+r)>>1;
if(up[mid].x<=x) l=mid;
else r=mid;
}
return up[l].y;
}
int getdown(int l,int r,int x) {
while(l+1<r) {
int mid=(l+r)>>1;
if(down[mid].x<x) l=mid;
else r=mid;
}
return down[r].y;
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
int n,m;
CLR(sum,0);
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) {
scanf("%d",&a[i]);
sum[i][0]=sum[i-1][0];
sum[i][1]=sum[i-1][1];
sum[i][i&1]+=a[i];
}
int dcnt=0,ucnt=0;
down[dcnt++]=node(0,0);
for(int i=0;i<n;i++) {
for(int j=i;j<n;j++) {
int x=sum[j][0]-sum[i-1][0],y=sum[j][1]-sum[i-1][1];
if((i%2==0)&&(j%2==0)) down[dcnt++]=node(x,y);
if(i%2&&j%2) up[ucnt++]=node(x,y);
}
}
sort(down+1,down+dcnt,cmp1);
int cnt=0;
for(int i=1;i<dcnt;i++)
if(down[i].x>down[cnt].x) down[++cnt]=down[i];
dcnt=cnt+1;
sort(up,up+ucnt,cmp2);
cnt=0;
for(int i=1;i<ucnt;i++)
if(up[i].y>up[cnt].y) up[++cnt]=up[i];
ucnt=cnt+1;
while(m--) {
int x,y;
scanf("%d%d",&x,&y);
if(x>sum[n-1][0]) {
printf("0");
continue;
}
int l=getdown(0,dcnt,x);
int r=getup(0,ucnt,x);
if(y>=l&&y<=r) printf("1");
else printf("0");
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: