QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#789461 | #8241. Master of Both V | ucup-team1004 | WA | 0ms | 20088kb | C++17 | 8.5kb | 2024-11-27 20:26:29 | 2024-11-27 20:26:29 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#ifdef DEBUG
#include"debug.h"
#else
#define debug(...) void()
#endif
#define all(x) (x).begin(),(x).end()
template<class T>
auto ary(T *a,int l,int r){
return vector<T>{a+l,a+1+r};
}
using ll=long long;
using ull=unsigned long long;
const int N=5e5+10;
using vec=complex<int>;
ll dot(const vec &a,const vec &b){
return 1ll*real(a)*real(b)+1ll*imag(a)*imag(b);
}
ll cross(const vec &a,const vec &b){
return dot(a,b*vec(0,-1));
}
int sign(const ll &a){
return a?(a>0?1:-1):0;
}
int T,n,op[N],ed[N];
vec a[N],b[N];
char ans[N];
void read(vec &a){
int x,y;
scanf("%d%d",&x,&y);
a=vec(x,y);
}
int hisk[N],hist[N],hisa[N],hisb[N];
void solve(int L,int R,int pos,vector<pair<int,int>>&o){
// debug("solve",L,R,pos,o);
auto trs=[&](vec p){
ll t=cross(b[pos]-a[pos],p);
if(t)return t>0?p:-p;
return dot(b[pos]-a[pos],p)>0?p:-p;
};
auto cmp1=[&](vec a,vec b){
return cross(a,b)>0;
};
vector<vec>arg;
for(auto [x,i]:o)if(i>0){
arg.push_back(trs(b[i]-a[i]));
}
sort(all(arg),cmp1);
arg.resize(unique(all(arg),[&](vec a,vec b){
return cross(a,b)==0;
})-arg.begin());
vector<vector<ll>>dis(arg.size());
auto find1=[&](vec a){
return lower_bound(all(arg),a,cmp1)-arg.begin();
};
for(auto [x,i]:o)if(i>0){
int &k=hisk[i]=find1(trs(b[i]-a[i]));
dis[k].push_back(cross(arg[k],a[i]));
}
for(auto &s:dis){
sort(all(s));
s.resize(unique(all(s))-s.begin());
}
auto find2=[&](int k,vec a){
return lower_bound(all(dis[k]),cross(arg[k],a))-dis[k].begin();
};
vector<vector<vector<ll>>>len(arg.size());
vector<vector<vector<vec>>>node(arg.size());
for(int i=0;i<arg.size();i++){
len[i].resize(dis[i].size());
node[i].resize(dis[i].size());
}
for(auto [x,i]:o)if(i>0){
int k=hisk[i];
int &t=hist[i]=find2(k,a[i]);
// debug(k,t,len[k]);
len[k][t].push_back(dot(a[i],arg[k]));
len[k][t].push_back(dot(b[i],arg[k]));
}
for(auto &p:len)for(auto &s:p){
sort(all(s));
s.resize(unique(all(s))-s.begin());
}
// debug("arg",arg);
// debug("dis",dis);
// debug("len",len);
for(int i=0;i<arg.size();i++){
for(int j=0;j<len[i].size();j++){
node[i][j].resize(len[i][j].size());
}
}
auto find3=[&](int k,int t,vec a){
return lower_bound(all(len[k][t]),dot(a,arg[k]))-len[k][t].begin();
};
for(auto [x,i]:o)if(i>0){
int k=hisk[i];
int t=hist[i];
int &pa=hisa[i]=find3(k,t,a[i]);
int &pb=hisb[i]=find3(k,t,b[i]);
// debug(k,t,pa,pb,node[k][t]);
node[k][t][pa]=a[i],node[k][t][pb]=b[i];
}
set<int>s1,sl,sr;
vector<vec>slp(arg.size()),slq(arg.size());
vector<vec>srp(arg.size()),srq(arg.size());
vector<set<int>>s2(arg.size());
vector<vector<multiset<int>>>s3(arg.size());
for(int i=0;i<arg.size();i++)s3[i].resize(dis[i].size());
auto check=[&](vec a,vec b,vec p,vec q){
if(cross(b-a,q-p)<=0)return true;
return
cross(b-a,p-a)>=0&&cross(b-a,q-a)>=0&&
cross(a-q,p-q)>=0&&cross(b-q,p-q)>=0;
};
int cur=0;
auto seg=[&](int k,int t){
return make_pair(node[k][t][*s3[k][t].begin()],node[k][t][*s3[k][t].rbegin()]);
};
auto add=[&](set<int>&s,vector<vec>&p,vector<vec>&q,int k,vec a,vec b){
// debug("add",k,a,b);
auto it=s.lower_bound(k);
if(it!=s.end()&&*it==k){
if(it!=s.begin()){
auto pre=prev(it);
cur-=!check(p[*pre],q[*pre],p[k],q[k]);
cur+=!check(p[*pre],q[*pre],a,b);
}
auto nex=next(it);
if(nex!=s.end()){
cur-=!check(p[k],q[k],p[*nex],q[*nex]);
cur+=!check(a,b,p[*nex],q[*nex]);
}
}else{
auto nex=it;
it=s.insert(k).first;
if(it!=s.begin()){
auto pre=prev(it);
if(nex!=s.end())cur-=!check(p[*pre],q[*pre],p[*nex],q[*nex]);
cur+=!check(p[*pre],q[*pre],a,b);
if(nex!=s.end())cur+=!check(a,b,p[*nex],q[*nex]);
}else if(nex!=s.end())cur+=!check(a,b,p[*nex],q[*nex]);
}
p[k]=a,q[k]=b;
};
auto del=[&](set<int>&s,vector<vec>&p,vector<vec>&q,int k){
// debug("del",k);
auto it=s.lower_bound(k);
if(it==s.end()||*it!=k)return;
auto nex=next(it);
if(nex!=s.end()){
cur-=!check(p[k],q[k],p[*nex],q[*nex]);
}
if(it!=s.begin()){
auto pre=prev(it);
cur-=!check(p[*pre],q[*pre],p[k],q[k]);
if(nex!=s.end()){
cur+=!check(p[*pre],q[*pre],p[*nex],q[*nex]);
}
}
};
auto pushl=[&](int k){
if(s2[k].empty())return del(sl,slp,slq,k);
vec p,q;
tie(p,q)=seg(k,*s2[k].begin());
if(s2[k].size()>1)return add(sl,slp,slq,k,p,q);
if(k==0){
if(!cross(b[pos]-a[pos],p-a[pos]))add(sl,slp,slq,k,p,q);
else del(sl,slp,slq,k);
return;
}
if(cross(q-p,a[pos]-p)>=0&&cross(q-p,b[pos]-p)>=0)add(sl,slp,slq,k,p,q);
else del(sl,slp,slq,k);
};
auto pushr=[&](int k){
if(s2[k].empty())return del(sr,srp,srq,k);
vec p,q;
tie(q,p)=seg(k,*s2[k].rbegin());
if(s2[k].size()>1)return add(sr,srp,srq,k,p,q);
if(k==0){
if(cross(b[pos]-a[pos],p-a[pos]))add(sr,srp,srq,k,p,q);
else del(sr,srp,srq,k);
return;
}
if(cross(q-p,a[pos]-p)>=0&&cross(q-p,b[pos]-p)>=0)add(sr,srp,srq,k,p,q);
else del(sr,srp,srq,k);
};
auto push=[&](int k){
pushl(k),pushr(k);
};
auto insert=[&](int id){
if(id==pos)return;
if(cross(b[pos]-a[pos],a[id]-a[pos])<0||cross(b[pos]-a[pos],b[id]-a[pos])<0){
return cur++,void();
}
int k=hisk[id],t=hist[id],pa=hisa[id],pb=hisb[id];
cur-=s2[k].size()>2;
auto it=s1.lower_bound(k);
if(s2[k].empty()){
auto nex=it==s1.end()?s1.begin():it;
auto pre=nex==s1.begin()?--s1.end():prev(nex);
it=s1.insert(k).first;
s2[k].insert(t);
s3[k][t].insert(pa);
s3[k][t].insert(pb);
}else if(s1.size()>1){
auto nex=next(it);
if(nex==s1.end())nex=s1.begin();
auto pre=it==s1.begin()?--s1.end():prev(it);
if(s3[k][t].empty())s2[k].insert(t);
s3[k][t].insert(pa);
s3[k][t].insert(pb);
}else{
if(s3[k][t].empty())s2[k].insert(t);
s3[k][t].insert(pa);
s3[k][t].insert(pb);
}
// debug("insert",id);
push(k);
cur+=s2[k].size()>2;
// debug("insert",id,cur);
};
auto print=[&](){
vec a,b;
for(int i:sl){
debug("L",i,slp[i],slq[i]);
}
for(int i:sr){
debug("R",i,srp[i],srq[i]);
}
};
auto erase=[&](int id){
if(id==pos)return;
if(cross(b[pos]-a[pos],a[id]-a[pos])<0||cross(b[pos]-a[pos],b[id]-a[pos])<0){
return cur--,void();
}
int k=hisk[id],t=hist[id],pa=hisa[id],pb=hisb[id];
cur-=s2[k].size()>2;
auto it=s1.lower_bound(k);
if(s1.size()>1){
auto nex=next(it);
if(nex==s1.end())nex=s1.begin();
auto pre=it==s1.begin()?--s1.end():prev(it);
s3[k][t].erase(s3[k][t].find(pa));
s3[k][t].erase(s3[k][t].find(pb));
if(s3[k][t].empty())s2[k].erase(t);
if(s2[k].empty())s1.erase(k);
}else{
s3[k][t].erase(s3[k][t].find(pa));
s3[k][t].erase(s3[k][t].find(pb));
if(s3[k][t].empty())s2[k].erase(t);
}
push(k);
cur+=s2[k].size()>2;
// debug("erase",id,cur);
};
auto chk=[&](){
if(sl.empty()||sr.empty())return 1;
int x=*sl.rbegin(),y=*sr.begin();
if(!check(slp[x],slq[x],srp[y],srq[y]))return 0;
x=*sr.rbegin(),y=*sl.begin();
if(!check(srp[x],srq[x],slp[y],slq[y]))return 0;
return 1;
};
// debug(arg);
// debug(dis);
// debug(len);
int k=hisk[pos],t=hist[pos],pa=hisa[pos],pb=hisb[pos];
s1.insert(k);
s2[k].insert(t);
s3[k][t].insert(pa);
s3[k][t].insert(pb);
for(int i=L,j=0;i<R;i++){
// debug(i);
for(;j<o.size()&&o[j].first<=i;j++){
int x=o[j].second;
// debug("update",x);
if(x>0)insert(x);
else erase(-x);
}
// if(i==4)print();
if(!cur&&chk())ans[i]='1';
// debug(i);
}
}
void solve(int L,int R,vector<pair<int,int>>&o){
for(int i=L;i<R;i++)ans[i]='0';
sort(all(o));
// debug("Solve",L,R,o);
solve(L,R,L,o);
swap(a[L],b[L]);
solve(L,R,L,o);
}
void work(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
static char str[9];
scanf("%s",str);
if(*str=='+'){
op[i]=0,ed[i]=n+1;
read(a[i]),read(b[i]);
}else scanf("%d",&op[i]),ed[op[i]]=i;
}
static int top,stk[N];
top=0;
for(int i=1;i<=n;i++)if(!op[i]){
if(!top||ed[i]>ed[stk[top]]){
if(top>1&&ed[stk[top-1]]>=i)top--;
stk[++top]=i;
}
}
stk[top+1]=n+1;
for(int i=1;i<=top;i++){
if(ed[stk[i]]<stk[i+1])ans[ed[stk[i]]]='1';
vector<pair<int,int>>o;
for(int j=stk[max(1,i-2)];j<stk[i+1];j++){
if(op[j])continue;
int l=max(stk[i],j),r=min(stk[i+1],ed[j]);
if(l<r)o.push_back({l,j}),o.push_back({r,-j});
}
solve(stk[i],stk[i+1],o);
}
for(int i=1;i<=n;i++)putchar(ans[i]);
puts("");
}
int main(){
for(scanf("%d",&T);T--;)work();
return 0;
}
#ifdef DEBUG
#include"debug.hpp"
#endif
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 20088kb
input:
4 8 + 0 0 1 0 + 5 5 1 3 + 2 0 2 1 + 9 7 6 2 + 1 2 2 2 - 4 + 0 1 0 2 - 2 5 + 0 0 1 1 + 0 1 1 2 + 0 2 1 3 - 2 + 1 1 10 10 4 + 0 0 1 1 + 0 0 1 0 + 0 0 0 1 - 1 4 + 0 0 1 1 + 0 0 1 1 - 1 - 2
output:
11000001 11011 1101 1111
result:
ok 4 lines
Test #2:
score: -100
Wrong Answer
time: 0ms
memory: 20008kb
input:
10 17 + -1 -3 -2 2 + 0 0 2 3 - 1 + 2 3 -3 0 + 1 -1 -2 3 + 0 -2 3 3 - 2 + -3 1 1 -3 - 5 + 0 -2 -1 1 - 4 - 6 + -1 3 -1 -2 + 2 3 0 1 - 10 - 8 + -3 3 2 3 31 + 3 0 2 1 + 0 -3 1 0 - 2 - 1 + 3 2 2 3 - 5 + -3 3 -3 -2 - 7 + -1 -1 3 3 - 9 + 0 1 0 -2 + -3 -2 2 0 + -1 1 0 -2 - 13 - 12 - 11 + 2 1 2 3 + 0 -2 2 3 ...
output:
10110000001100010 1111111111100011111100111111100 10 11100000001101 111001 11111101111 1 11111111 11111 11111
result:
wrong answer 1st lines differ - expected: '10110000000000000', found: '10110000001100010'