QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#697169 | #7015. Rikka with Illuminations | pengpeng_fudan | WA | 15ms | 3784kb | C++23 | 9.9kb | 2024-11-01 11:34:36 | 2024-11-01 11:34:37 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
//注意叉乘是否会爆ll
//注意凸包的最后一个点都是第一个点
//注意凸包都是逆时针的
//注意每次选凸包基准点都是x最小然后y最大
template<class T>
struct vec{
T x,y;
vec(T _x=0,T _y=0):x(_x),y(_y){};
int qx(){//四一二三排序,按需修改
if(x>=0&&y>=0) return 2;
if(x<0&&y>=0) return 3;
if(x<0&&y<0) return 4;
if(x>=0&&y<0) return 1;
return -1;
}
void print(){cerr<<x<<' '<<y<<'\n';}
bool operator<(vec a){
if(qx()!=a.qx()) return qx()<a.qx();
else{
T p=x*a.y,q=y*a.x;
if(p!=q) return p>q;
else if(a.y==0) return abs(x)>abs(a.x);
else return abs(y)>abs(a.y);
}
}
T len2(){return x*x+y*y;}
vec operator *(T k){return {x*k,y*k};}
vec operator +(vec a){return {x+a.x,y+a.y};}
vec operator -(vec a){return {x-a.x,y-a.y};}
T operator *(vec a){return x*a.x+y*a.y;}
T operator ^(vec a){return x*a.y-y*a.x;}
bool operator ==(vec a){return x==a.x&&y==a.y;}
bool operator !=(vec a){return (x!=a.x||y!=a.y);}
};
template<class T>
bool check_on_line_dir(vec<T> p,vec<T> q){
vec<__int128_t> p1={p.x,p.y};
vec<__int128_t> q1={q.x,q.y};
if((p1*q1)>=0&&(p1^q1)==0) return true;
return false;
}
template<class T>
vector<vec<T>> build_convex(vector<vec<T>> pot){//输入点集输出凸包(最后一个点和第一个点是一个点)
sort(pot.begin(),pot.end(),[&](vec<T> a,vec<T> b){if(a.x!=b.x) return a.x<b.x;return a.y>b.y;});
int n=pot.size();
int lo=0;
vector<vec<T>> res;
for(int i=0;i<n;i++){
while(lo>=2&&((res[lo-1]-res[lo-2])^(pot[i]-res[lo-1]))<=0) lo--,res.pop_back();
res.push_back(pot[i]),lo++;
}
int pre=lo;
for(int i=n-2;i>=0;i--){
while(lo>=pre+1&&((res[lo-1]-res[lo-2])^(pot[i]-res[lo-1]))<=0) lo--,res.pop_back();
res.push_back(pot[i]),lo++;
}
return res;
}
template<class T>
double convex_peri(vector<vec<T>> convex){//输入凸包(最后一个点和第一个点是一个点),输出凸包长度
double len=0;
int sz=convex.size();
for(int i=1;i<=sz-1;i++){
len+=sqrt((convex[i]-convex[i-1]).len2());
}
return len;
}
template<class T>
double convex_area(vector<vec<T>> convex){//输入凸包(最后一个点和第一个点是一个点),输出凸包面积
T area=0;
int sz=convex.size();
for(int i=0;i<sz-2;i++){
area+=abs((convex[0]-convex[i+1])^(convex[0]-convex[i+2]));
}
return (double)area/2;
}
//https://tsinghua.contest.codeforces.com/group/3T118PLOiT/contest/544779/problem/I
template<class T>
void reorder(vector<vec<T>>& p){//将凸包变成先x最小再y最小,输入需要满足(最后一个点和第一个点是一个点)
p.pop_back();
rotate(p.begin(), min_element(p.begin(),p.end(), [&](vec<T> a, vec<T> b) {
return make_pair(a.x, -a.y) < make_pair(b.x, -b.y);
}), p.end());p.push_back(p[0]);
}
template<class T>
vector<vec<T>> mincowsky_sum(vector<vec<T>> a,vector<vec<T>> b){//传入的是两个已经建好的且为逆时针的凸包(最后一个点和第一个点是一个点)//注意输出的凸包的相邻两个边可能是平行的
reorder(a),reorder(b);//让a和b的第0个点是x最小然后y最大
vector<vec<T>> res;
vec<T> st=a[0]+b[0];
int s1=a.size(),s2=b.size();
int l1=0,l2=0;
res.push_back(st);
while(l1!=s1-1||l2!=s2-1){
if(l1==s1-1||(l2!=s2-1&&b[l2+1]-b[l2]<a[l1+1]-a[l1])){
st=st+(b[l2+1]-b[l2]);l2++;
}
else {
st=st+(a[l1+1]-a[l1]);l1++;
}
res.push_back(st);
}
return res;
}
template<class T>
struct line{
vec<T> k,b;//k为方向,b为线上任意一个点,射线的话b为端点
line(vec<T> dir,vec<T> pot):k(dir),b(pot) {}
};
template<class T>
vec<double> getnode(line<T> p,line<T> q){
assert((p.k^q.k)!=0);
double t=(double)((p.b-q.b)^q.k)/(q.k^p.k);
vec<double> ans;
ans.x=p.b.x+p.k.x*t;
ans.y=p.b.y+p.k.y*t;
return ans;
};
template<class T>
struct convex_hull_trick{//静态凸包求单点值
vector<line<T>> convex;// 注意line.b不是射线端点,存的仅仅是直线在凸包上的顺序
bool _mo;
convex_hull_trick(vector<line<T>> line_all,int mo){//mo=1求极大,mo=0求极小
_mo=mo;
for(auto& [k,b]:line_all){
assert(k.x);
if(k.x<0) {k.x=-k.x,k.y=-k.y;}
}
line<T> line_y(vec<T>(0,1),vec<T>(0,0));
if(mo==0) sort(line_all.begin(),line_all.end(),[&](line<T> a,line<T> b){
if(!check_on_line_dir(a.k,b.k)) return b.k<a.k;
else return getnode(line_y,a).y<getnode(line_y,b).y;
});
else sort(line_all.begin(),line_all.end(),[&](line<T> a,line<T> b){
if(!check_on_line_dir(a.k,b.k)) return a.k<b.k;
else return getnode(line_y,a).y>getnode(line_y,b).y;
});
int sz=line_all.size();
int lo=0;
for(int i=0;i<sz;i++){
if(i==0) {convex.push_back(line_all[i]);lo++;continue;}
if(check_on_line_dir(line_all[i].k,line_all[i-1].k)) continue;
while(lo>1){
if(getnode(convex[lo-2],convex[lo-1]).x>=getnode(convex[lo-1],line_all[i]).x) {
lo--;convex.pop_back();
}
else break;
}
convex.push_back(line_all[i]);lo++;
}
}
double get_y(double x){
int lo=0,ro=(int)convex.size()-1;
while(lo<ro){
int mid=(lo+ro)>>1;
if(getnode(convex[mid],convex[mid+1]).x<=x) lo=mid+1;
else ro=mid;
}
return convex[lo].b.y+convex[lo].k.y/convex[lo].k.x*(x-convex[lo].b.x);
}
};
const double eps=1e-9;
template<class T>
double half_plane(vector<line<T>> line_all){//半平面交,目标面积必须在输入有向线段左边
vector<vec<double>> convex;
line<T> line_y(vec<T>(0,1),vec<T>(0,0));
sort(line_all.begin(),line_all.end(),[&](line<T> a,line<T> b){
if(!check_on_line_dir(a.k,b.k)) return a.k<b.k;
else return ((b.b-a.b)^a.k)>0;
});
int lo=0,ro=-1;
vector<line<T>> res;
auto check=[&](line<T> l,line<T> mid,line<T> r)->bool {//l,mid的交点在r左边
return ((getnode(l,mid)-vec<double>(r.b.x,r.b.y))^vec<double>(r.k.x,r.k.y))<eps;
};
int sz=line_all.size();
for(int i=0;i<sz;i++){
if(i==0) {res.push_back(line_all[i]);ro++;continue;}
if(check_on_line_dir(line_all[i].k,line_all[i-1].k)) continue;
while(lo<ro&&!check(res[ro-1],res[ro],line_all[i])) {res.pop_back();ro--;}
while(lo<ro&&!check(res[lo],res[lo+1],line_all[i])) lo++;
res.push_back(line_all[i]);ro++;
}
while(lo<ro&&!check(res[ro-1],res[ro],res[lo])) ro--;
if(ro-lo<=1) return 0;
if(!check(res[ro],res[lo],res[lo+1])) return -1;
for(int i=lo;i<=ro-1;i++) convex.push_back(getnode(res[i],res[i+1]));
convex.push_back(getnode(res[ro],res[lo]));convex.push_back(convex[0]);
return convex_area(convex);
}
pair<int,int> get_pot_convex_cut_line(vec<ll> v,vector<vec<ll>>& hull){//要传引用否则复杂度不对,sz-1和0是同一个点所以返回时把sz-1变成0了
int sz=hull.size();
int lo=0,ro=sz-2;
int flag=((((hull[1]-v)^(hull[0]-v))>=0)?1:-1);
while(lo<ro){
int mid=(lo+ro+1)>>1;
if((((hull[mid]-v)^(hull[0]-v))*flag)>=0) lo=mid;
else ro=mid-1;
}
pair<int,int> lcut={0,lo},rcut={lo+1,sz-1};
pair<int,int> ans;
if(flag==1) swap(lcut,rcut);
lo=lcut.first,ro=lcut.second;
while(lo<ro){
int mid=(lo+ro)>>1;
if(((hull[mid+1]-hull[mid])^(v-hull[mid]))>=0) lo=mid+1;
else ro=mid;
}
ans.first=(lo==sz-1?0:lo);
lo=rcut.first,ro=rcut.second;
while(lo<ro){
int mid=(lo+ro)>>1;
if(((hull[mid+1]-hull[mid])^(hull[mid]-v))>0) lo=mid+1;
else ro=mid;
}
ans.second=(lo==sz-1?0:lo);
return ans;
}
void solve(void) {
int n,m;
cin>>n>>m;
vector<vec<ll>> hull;
for(int i=0;i<n;i++){
int x,y;
cin>>x>>y;hull.push_back({x,y});
}
hull.push_back(hull[0]);
vector<pair<int,int>> maxn(2*n+1);
for(int i=1;i<=m;i++){
vec<ll> v;cin>>v.x>>v.y;
pair<int,int> res=get_pot_convex_cut_line(v,hull);
// cerr<<res.first<<' '<<res.second<<'\n';
if(res.first<=res.second) {
maxn[res.first]=max(maxn[res.first],{res.second,i});
maxn[res.first+n]=max(maxn[res.first+n],{res.second+n,i});
}
else{
maxn[res.first]=max(maxn[res.first],{res.second+n,i});
}
}
vector<int> res;
for(int i=0;i<n;i++){
vector<int> ans;
int lo=i,ro=maxn[i].first;ans.push_back(maxn[i].second);
bool flag=false;
while(lo<=ro){
if(lo>=i+n) {flag=true;break;}
pair<int,int> mq={0,0};
for(int j=lo;j<=ro;j++){
mq=max(mq,maxn[j]);
}
lo=ro+1,ro=mq.first,ans.push_back(mq.second);
}
if(flag&&(res.empty()||res.size()>ans.size())) res=ans;
}
if(res.size()==0) {cout<<"-1\n";return ;}
cout<<res.size()<<'\n';
if(!res.empty()){
int sz=res.size();
for(int j=0;j<sz;j++){
cout<<res[j]<<" \n"[j==sz-1];
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--) solve();
return 0;
}
/*
4 4
0 0
1 0
1 1
0 1
3 3
-1 3
2 3
0 -10
*/
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 3784kb
input:
1 3 3 0 0 1 0 0 1 -1 -1 3 -1 -1 3
output:
2 2 1
result:
ok 1 cases.
Test #2:
score: -100
Wrong Answer
time: 15ms
memory: 3568kb
input:
100 13 17 -976 -766 -628 -956 462 -987 967 -997 981 -123 919 115 847 336 692 789 350 908 -558 996 -843 944 -944 400 -974 -476 -41876798 919231678 -375313647 26070145 -288061228 527643156 -93144407 730297 93699145 -260606010 -393321698 -339399089 644245933 784344503 -731740672 525632046 -32141854 114...
output:
3 16 17 16 -1 -1 -1 -1 3 17 20 14 -1 4 27 3 22 13 -1 -1 -1 9 5 9 17 7 3 14 2 10 12 4 6 10 5 7 -1 4 3 2 7 3 -1 -1 -1 -1 -1 5 8 11 10 21 8 5 13 3 12 7 13 5 5 7 1 2 5 5 17 48 25 13 17 5 33 22 38 32 33 6 37 40 22 6 38 39 37 90 58 66 70 47 57 64 74 71 83 26 76 38 51 7 20 84 4 9 12 14 32 45 24 78 68 73 67...
result:
wrong answer In case 1, the illuminant with index 16 has been selected before.