hdu 4760

题目

大意:  3种操作  E i n,对应n个区间,每个区间加一个标记i;

                         D i ,抹去前面的标记i;

                         F s t.如果点s和点t的标记有交集则输出"F",否则输出"D':

 

想法:  我悔过,比赛时,感觉题目太复杂,没管它,赛后来看了看,没想到暴力能水过.

        先把数据全部读入,然后把点离散化,然后就直接暴力.

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define N 32769
typedef long long ll;
#pragma comment(linker, "/STACK:1024000000,1024000000")

map<ll,int>m;
map<int,int>id;

struct
{
    int id,num;
    ll s[15],t[15];
}E[N];
struct
{
    ll s,t;
}F[N];
int D[N],nume,numf,numd,a,b,c,d,e;
char op[N][3],s[40];

void change(int a,int b,int c,int d)
{
    for(int i=7;i>=0;i--)
    {
        s[i]=a%2+'0';
        a/=2;
    }
    for(int i=15;i>=8;i--)
    {
        s[i]=b%2+'0';
        b/=2;
    }
    for(int i=23;i>=16;i--)
    {
        s[i]=c%2+'0';
        c/=2;
    }
    for(int i=31;i>=24;i--)
    {
        s[i]=d%2+'0';
        d/=2;
    }
    s[32]='\0';

}


vector<int>query[N*15];

int main()
{

    m.clear();
    nume=0,numf=0,numd=0;
    int numop=0;
    while(scanf("%s",op[numop])!=EOF)
    {
        if(op[numop][0]=='D')
        {
            scanf("%d",&a);
            D[numd++]=a;
        }
        else if(op[numop][0]=='F')
        {

            scanf("%d.%d.%d.%d",&a,&b,&c,&d);
            change(a,b,c,d);
            ll z=0;
            for(int i=31;i>=0;i--) z+=(s[i]-'0')*(1<<(31-i));
            F[numf].s=z;
            if(m[z]==0) m[z]=1;

            scanf("%d.%d.%d.%d",&a,&b,&c,&d);
            change(a,b,c,d);
            z=0;
            for(int i=31;i>=0;i--) z+=(s[i]-'0')*(1<<(31-i));
            F[numf++].t=z;
            if(m[z]==0) m[z]=1;
        }
        else if(op[numop][0]=='E')
        {
            scanf("%d%d",&E[nume].id,&E[nume].num);
            id[E[nume].id]=nume+1;
            for(int j=0;j<E[nume].num;j++)
            {
                scanf("%d.%d.%d.%d/%d",&a,&b,&c,&d,&e);
                change(a,b,c,d);
                //for(int i=e;i<=31;i++)s[i]='0';
                ll z=0;
                for(int i=31;i>=0;i--) z+=(s[i]-'0')*(1<<(31-i));
                E[nume].s[j]=z;
                if(m[z]==0) m[z]=1;

                ll w=z|((1<<(32-e))-1);
                E[nume].t[j]=w;
                if(m[w]==0) m[w]=1;

            }
            nume++;
        }
        numop++;
    }

    int k=1;
    map<ll,int>::iterator it;
    vector<int>::iterator zz;
    for(it=m.begin();it!=m.end();it++)
    {
        m[it->first]=k++;
    }

    int fe=0,ff=0,fd=0;
    for(int i=0;i<numop;i++)
    {
        if(op[i][0]=='E')
        {
            for(int j=0;j<E[fe].num;j++)
            {
                for(int r=m[E[fe].s[j]];r<=m[E[fe].t[j]];r++)
                    query[r].push_back(E[fe].id);
            }
            fe++;
        }
        else if(op[i][0]=='D')
        {
            int x=D[fd++];
            x=id[x]-1;
            for(int j=0;j<E[x].num;j++)
            {
                for(int r=m[E[x].s[j]];r<=m[E[x].t[j]];r++)
                    for(zz=query[r].begin();zz!=query[r].end();zz++)
                    {
                        if((*zz)==E[x].id)
                        {
                            query[r].erase(zz);break;
                        }
                    }
            }
        }
        else if(op[i][0]=='F')
        {
            int x=m[F[ff].s],y=m[F[ff++].t];
            int tag=1,flag=1;
            if(query[x].size()*query[y].size()<=0) tag=0;
            for(int j=0;j<query[x].size()&&flag;j++)
                for(int r=0;r<query[y].size()&&flag;r++)
            {
                if(query[x][j]==query[y][r])
                {
                    flag=0;
                }
            }
            printf("%s\n",(!flag&&tag)?"F":"D");
        }

    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值