CTU Open Contest 2016 Suspicious Samples

来源:互联网 发布:安卓最快的数据库 编辑:程序博客网 时间:2024/06/08 05:19

题目链接:点击打开链接

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;const int MAXN=100010;typedef long long llt;int segTree_max[MAXN<<2];int segTree_min[MAXN<<2];llt segTree_sum[MAXN<<2];int v[MAXN];int t[MAXN];void Build(int node,int begin,int end){    if(begin==end){segTree_max[node]=segTree_min[node]=segTree_sum[node]=v[begin];return;}    int mid=(begin+end)/2;    Build(node*2,begin,mid);    Build(node*2+1,mid+1,end);    segTree_max[node]=max(segTree_max[node*2],segTree_max[node*2+1]);    segTree_min[node]=min(segTree_min[node*2],segTree_min[node*2+1]);    segTree_sum[node]=segTree_sum[node*2]+segTree_sum[node*2+1];}int query_max(int node,int begin,int end,int l,int r){    if(begin==l&&end==r) return segTree_max[node];    int mid=(begin+end)/2;    if(r<=mid) return query_max(node*2,begin,mid,l,r);    if(l>mid) return query_max(node*2+1,mid+1,end,l,r);    return max(query_max(node*2,begin,mid,l,mid),query_max(node*2+1,mid+1,end,mid+1,r));}int query_min(int node,int begin,int end,int l,int r){    if(begin==l&&end==r) return segTree_min[node];    int mid=(begin+end)/2;    if(r<=mid) return query_min(node*2,begin,mid,l,r);    if(l>mid) return query_min(node*2+1,mid+1,end,l,r);    return min(query_min(node*2,begin,mid,l,mid),query_min(node*2+1,mid+1,end,mid+1,r));}llt query_sum(int node,int begin,int end,int l,int r){    if(begin==l&&end==r) return segTree_sum[node];    int mid=(begin+end)/2;    if(r<=mid) return query_sum(node*2,begin,mid,l,r);    if(l>mid) return query_sum(node*2+1,mid+1,end,l,r);    return query_sum(node*2,begin,mid,l,mid)+query_sum(node*2+1,mid+1,end,mid+1,r);}char buf1[10],buf2[10];int times;int main(){    int N,K;    //freopen("C:\\Users\\Administrator\\Desktop\\8-12\\data\\11714\\1.std.in","r",stdin);    //freopen("D:\\test.txt","w",stdout);    while(scanf("%d",&N)!=EOF)    {        for(int i=1;i<=N;i++)            scanf("%d%d",&t[i],&v[i]);        Build(1,1,N);        scanf("%d",&K);        for(int i=1;i<=K;i++)        {            int cnt=0;            scanf("%s%s%d",buf1,buf2,×);            for(int j=2;j<=N;j++)            {                //找到每个查询开始的时间和结束的时间                int upos=1,dpos=j-1;                if(t[j]-t[j-1]>times) continue;                //while((t[j]-t[upos+1]>times)&&(upos<dpos)) upos++;                //二分法查找查询区间,否则会TLE                int left=upos,right=dpos;                while(left<=right)                {                    int mid=(right-left)/2+left;                    if(t[j]-t[mid]<=times) right=mid-1;                    else left=mid+1;                }                upos=left;                //printf("upos :%d dpos :%d\n",upos,dpos);                if(strcmp(buf1,"gt")==0)                {                    double _cmp;                    if(strcmp(buf2,"max")==0) _cmp=query_max(1,1,N,upos,dpos);                    else if(strcmp(buf2,"min")==0) _cmp=query_min(1,1,N,upos,dpos);                    else _cmp=1.0*query_sum(1,1,N,upos,dpos)/(dpos-upos+1);                    if(_cmp<v[j]) cnt++;                }                else                {                    double _cmp;                    if(strcmp(buf2,"max")==0) _cmp=query_max(1,1,N,upos,dpos);                    else if(strcmp(buf2,"min")==0) _cmp=query_min(1,1,N,upos,dpos);                    else _cmp=1.0*query_sum(1,1,N,upos,dpos)/(dpos-upos+1);                    if(_cmp>v[j]) cnt++;                }            }            printf("%d\n",cnt);        }    }    return 0;}