大意: 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;
}