QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#303118 | #7803. H-Shaped Figures | PhantomThreshold | WA | 1ms | 3700kb | C++20 | 5.1kb | 2024-01-11 18:33:01 | 2024-01-11 18:33:02 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
using ll=__int128;
struct point
{
ll x,y;
point operator+(const point &p)const{return (point){x+p.x,y+p.y};}
point operator-(const point &p)const{return (point){x-p.x,y-p.y};}
ll operator*(const point &p)const{return x*p.y-y*p.x;}
ll operator^(const point &p)const{return x*p.x+y*p.y;}
bool operator==(const point &p)const{return x==p.x and y==p.y;}
friend istream& operator>>(istream &is,point &p)
{
long long a,b;
is>>a>>b;
p.x=a;p.y=b;
return is;
}
friend ostream& operator<<(ostream &os,const point &p)
{
os<<'('<<(long long)p.x<<','<<(long long)p.y<<')';
return os;
}
point turn(const point &p)const
{
point pc=p;//pc.y*=-1;
return (point){*this^pc,-(*this*pc)};
}
};
bool online(const point &a,const point &b,const point &c)
{
return (c-a)*(b-a)==0;
}
bool inmid(ll a,ll b,ll c)
{
if(a>b)swap(a,b);
return a<=c and c<=b;
}
bool inmid(const point &a,const point &b,const point &c)
{
return inmid(a.x,b.x,c.x) and inmid(a.y,b.y,c.y);
}
bool onseg(const point &a,const point &b,const point &c)
{
return online(a,b,c) and inmid(a,b,c);
}
int main()
{
ios_base::sync_with_stdio(false);cin.tie(0);
int T;
cin>>T;
while(T--)
{
point P,Q;
int n;
cin>>P>>Q>>n;
vector<pair<point,point>> segs(n+5),Pseg,Qseg;
for(int i=1;i<=n;i++)
{
cin>>segs[i].first>>segs[i].second;
}
Q=Q-P;
P=P-P;
for(int i=1;i<=n;i++)
{
segs[i].first=segs[i].first-P;
segs[i].second=segs[i].second-P;
}
for(int i=1;i<=n;i++)
{
segs[i].first=segs[i].first.turn(Q);
segs[i].second=segs[i].second.turn(Q);
}
Q=Q.turn(Q);
// cerr<<P<<' '<<Q<<endl;
// for(int i=1;i<=n;i++)
// cerr<<segs[i].first<<' '<<segs[i].second<<endl;
for(int i=1;i<=n;i++)
{
if(online(segs[i].first,segs[i].second,P) and online(segs[i].first,segs[i].second,Q))continue;
if(onseg(segs[i].first,segs[i].second,P) and segs[i].first!=P and segs[i].second!=P)Pseg.push_back(segs[i]);
if(onseg(segs[i].first,segs[i].second,Q) and segs[i].first!=Q and segs[i].second!=Q)Qseg.push_back(segs[i]);
}
/*
cerr<<"P:"<<endl;
for(auto [u,v]:Pseg)
cerr<<u<<' '<<v<<endl;
cerr<<"Q:"<<endl;
for(auto [u,v]:Qseg)
cerr<<u<<' '<<v<<endl;
*/
long long ans=1ll*Pseg.size()*Qseg.size();
//y>0 part
{
for(auto &[u,v]:Pseg)
{
if(u.y<v.y)swap(u,v);
}
for(auto &[u,v]:Qseg)
{
if(u.y<v.y)swap(u,v);
}
sort(Qseg.begin(),Qseg.end(),[&](const pair<point,point> &p,const pair<point,point> &q){return (p.first-Q)*(q.first-Q)<=0;});
vector<pair<point,int>> events;
int a=(int)Pseg.size(),b=(int)Qseg.size();
for(int i=0;i<a;i++)
{
events.emplace_back(Pseg[i].first,-1);
}
for(int i=0;i<b;i++)
{
events.emplace_back(Qseg[i].first,i);
}
sort(events.begin(),events.end(),[&](const pair<point,int> &p,const pair<point,int> &q){return p.first*q.first>0 or (p.first*q.first==0 and p.second<q.second);});
vector<int> BIT(b+5);
auto change=[&](int pos,int d)
{
pos++;
for(int x=pos;x<=b;x+=x&-x)
BIT[x]+=d;
};
auto query=[&](int pos)
{
pos++;
int ret=0;
for(int x=pos;x;x-=x&-x)
ret+=BIT[x];
return ret;
};
for(int i=0;i<b;i++)change(i,1);
for(const auto &[p,id]:events)
{
if(id==-1)
{
int l=-1,r=b-1;
while(l<r)
{
int mid=(l+r+1)/2;
if((Qseg[mid].first-Q)*(p-Q)<=0)l=mid;
else r=mid-1;
}
// cerr<<"query1 "<<p<<' '<<r<<endl;
ans-=query(r);
}
else
{
change(id,-1);
// cerr<<"delete1 "<<p<<' '<<id<<endl;
}
}
}
// cerr<<"? "<<ans<<endl;
//y<0 part
{
for(auto &[u,v]:Pseg)
{
if(u.y>v.y)swap(u,v);
u.y*=-1;v.y*=-1;
}
for(auto &[u,v]:Qseg)
{
if(u.y>v.y)swap(u,v);
u.y*=-1;v.y*=-1;
}
sort(Qseg.begin(),Qseg.end(),[&](const pair<point,point> &p,const pair<point,point> &q){return (p.first-Q)*(q.first-Q)<=0;});
vector<pair<point,int>> events;
int a=(int)Pseg.size(),b=(int)Qseg.size();
for(int i=0;i<a;i++)
{
events.emplace_back(Pseg[i].first,-1);
}
for(int i=0;i<b;i++)
{
events.emplace_back(Qseg[i].first,i);
}
sort(events.begin(),events.end(),[&](const pair<point,int> &p,const pair<point,int> &q){return p.first*q.first>0 or (p.first*q.first==0 and p.second<q.second);});
vector<int> BIT(b+5);
auto change=[&](int pos,int d)
{
pos++;
for(int x=pos;x<=b;x+=x&-x)
BIT[x]+=d;
};
auto query=[&](int pos)
{
pos++;
int ret=0;
for(int x=pos;x;x-=x&-x)
ret+=BIT[x];
return ret;
};
for(int i=0;i<b;i++)change(i,1);
for(const auto &[p,id]:events)
{
if(id==-1)
{
int l=-1,r=b-1;
while(l<r)
{
int mid=(l+r+1)/2;
if((Qseg[mid].first-Q)*(p-Q)<=0)l=mid;
else r=mid-1;
}
// cerr<<"query2 "<<p<<' '<<r<<endl;
ans-=query(r);
}
else
{
// cerr<<"delete2 "<<p<<' '<<id<<endl;
change(id,-1);
}
}
}
cout<<ans<<"\n";
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3548kb
input:
1 0 0 4 0 8 0 0 2 1 -1 -1 2 2 3 3 5 -3 0 2 6 -1 2 -2 5 1 -1 1 3 -3 -1 0 2 0 -1 -1 2 2
output:
6
result:
ok 1 number(s): "6"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3700kb
input:
1 -1 0 0 1 2 1 1 0 -1 1 1 0 1
output:
0
result:
ok 1 number(s): "0"
Test #3:
score: 0
Accepted
time: 0ms
memory: 3604kb
input:
1 5 -5 7 2 2 -6 8 2 6 -7 -10 -5 10
output:
0
result:
ok 1 number(s): "0"
Test #4:
score: 0
Accepted
time: 0ms
memory: 3556kb
input:
10 -4 7 -10 -4 3 -3 3 -6 -9 -9 -3 -6 -9 -7 0 6 5 0 -5 -3 5 5 -7 -3 -5 -6 6 1 -3 4 1 -4 -4 7 -2 9 3 8 -4 -3 9 0 -9 -3 7 8 25 4 6 4 5 4 -6 -9 -6 -8 -8 10 -6 6 4 2 -7 2 -5 10 -4 -1 -9 -2 -1 -9 -10 6 6 -5 1 -5 -2 -1 -10 -6 1 9 -9 0 -4 -2 -4 -1 3 2 5 -10 1 9 7 6 4 -2 -5 -4 -3 -3 -5 5 -8 3 0 -6 1 6 3 7 2 ...
output:
0 0 0 0 0 0 0 0 0 0
result:
ok 10 numbers
Test #5:
score: -100
Wrong Answer
time: 1ms
memory: 3608kb
input:
10 -3 7 1 9 285 9 -5 0 8 -3 0 -1 8 -6 -7 8 -10 -3 -8 9 2 -4 9 -8 4 6 -10 9 -2 -10 -5 -2 10 7 -10 -2 2 7 7 10 -5 7 8 -7 -1 2 4 7 -4 3 -10 -9 8 7 -7 6 -3 10 10 -6 -2 -2 7 -8 3 0 -10 -9 5 7 3 -3 7 6 -8 -5 6 8 -8 7 7 -9 -1 10 7 -10 6 -4 -1 -6 -10 -6 0 9 6 2 -9 0 6 -1 -1 0 2 6 0 -9 -8 6 -2 10 7 -7 -5 2 5...
output:
0 0 0 2 0 0 0 0 0 0
result:
wrong answer 1st numbers differ - expected: '1', found: '0'