20190729
A.
黑大帥統(tǒng)治古古怪界后,一直在玩一種很奇葩的游戲。在一個(gè)二維平面上,他先復(fù)制了n個(gè)小A,把他們放在不同的位置,然后射出一條ax+by+c=0的基因光線,寬度為d,即離這條直線的距離不大于d的小A會被射中。當(dāng)然,某些悲劇的小A就會被射中,并變成黑小A。當(dāng)然,這不是重點(diǎn)。玩了很久后,黑大帥猛然發(fā)現(xiàn),自己竟然一次都沒有射中小A。黑大帥怒了,于是他開啟了作弊模式,將c改成自己想要的任意數(shù)值。現(xiàn)在,黑大帥想知道,在開啟了作弊模式后,他射出一道基因光線最多能擊中幾個(gè)小A。
輸入格式
第一行五個(gè)數(shù)字a,b,d,n,接下來n行每行兩個(gè)數(shù)字x,y表示這個(gè)小A的坐標(biāo)。
輸出格式
一行一個(gè)數(shù)字表示最多能擊中幾個(gè)小A。
樣例輸入
1 -1 0.707106782 5 0 0 1 0 0 1 2 0 2 1樣例輸出
4數(shù)據(jù)范圍
50%的數(shù)據(jù)滿足a=0;
100%的數(shù)據(jù)滿足n<=100000,其余所有數(shù)值均為絕對值不大于1000的實(shí)數(shù)。
解
考慮 \(a=0\) 的情況。
直接按y坐標(biāo)排序然后two-pointers。
然后就能想到用點(diǎn)到直線的距離公式把點(diǎn)排序。
公式:有一點(diǎn) \(P(x_0,y_0)\) ,直線 \(Ax+By+C=0\) ,則 \[d=\frac{Ax_0+By_0+C}{\sqrt{A^2+B^2}}\]
當(dāng) \(P\) 在直線的不同側(cè)時(shí), \(d\) 的符號也不同。
Code
#include<bits/stdc++.h> using namespace std; const int maxn=100003; const double eps=1e-8; int sgn(double x){return x<-eps?-1:x>eps;} struct point{double x,y; }pnt[maxn]; int n,ans; double a,b,d,sq; double dis(point p){return a*p.x+b*p.y; } int main(){scanf("%lf%lf%lf%d",&a,&b,&d,&n);sq=sqrt(a*a+b*b);for(int i=1;i<=n;i++)scanf("%lf%lf",&pnt[i].x,&pnt[i].y);sort(pnt+1,pnt+n+1,[](point p,point q){return sgn(dis(p)-dis(q))<0;});for(int i=1,j=1;i<=n;i++){for(;j<=n&&sgn((dis(pnt[j])-dis(pnt[i]))/sq-d*2)<=0;j++);ans=max(ans,j-i);}printf("%d\n",ans);return 0; }B.
noip2011就要來了,W校的同學(xué)們不僅看重這次比賽,更看重noip2011和誰住在同一個(gè)房間。同學(xué)之間的關(guān)系好壞可以用一個(gè)親密值表示,親密值越大,兩個(gè)同學(xué)關(guān)系越好。小A作為W校信息組的組長,自然想要讓同學(xué)們在比賽前能好好休息,放松心情,讓同學(xué)們在賽場上能夠超常發(fā)揮。他現(xiàn)在知道自己預(yù)訂的房間都是雙人間,且知道這n個(gè)同學(xué)之間的關(guān)系。n個(gè)同學(xué)的關(guān)系可以用一個(gè)n條雙向邊的連通圖來描述,即某個(gè)同學(xué)只愿意和與他有邊相連的同學(xué)住同一個(gè)房間,邊權(quán)即為兩個(gè)同學(xué)的親密值。數(shù)據(jù)保證沒有重邊、自環(huán)。現(xiàn)在小A想知道在讓所有同學(xué)的要求滿足的情況下,親密值最低的一對同學(xué)親密值最高是多少。
輸入格式
第一行一個(gè)正整數(shù)n,下面n行每行三個(gè)數(shù)u,v,w,表示u到v有一條邊權(quán)為w的雙向邊。
輸出格式
假如無論如何都無法滿足所有同學(xué)的要求,輸出”no answer”,否則輸出親密值最低的一對同學(xué)的最高親密值。
樣例輸入
4 1 2 3 2 3 10 3 4 3 1 4 1樣例輸出
3數(shù)據(jù)范圍
50%的數(shù)據(jù)滿足n<=20;
80%的數(shù)據(jù)滿足n<=1000;
100%的數(shù)據(jù)滿足n<=100000,-10^9<=w<=10^9
解
首先這是一棵基環(huán)樹,就不關(guān)二分圖和網(wǎng)絡(luò)流什么事了。
乍一看像是二分答案然后跑dp。
實(shí)際上觀察發(fā)現(xiàn),為保證每一個(gè)節(jié)點(diǎn)都能被另一個(gè)節(jié)點(diǎn)匹配,我們建一個(gè)隊(duì)列,從葉子開始,遍歷到每一個(gè)度數(shù)為1的節(jié)點(diǎn),刪除它和它父親,并把新產(chǎn)生的度為1的節(jié)點(diǎn)推入隊(duì)列,以此類推,最后要么所有節(jié)點(diǎn)都匹配成功,要么還剩下一個(gè)環(huán)。如果是環(huán)就只會存在兩種方案,dfs把環(huán)拉出來統(tǒng)計(jì)即可。
C.
小A是小B家的園丁。小B的家里有n棵樹,第i棵樹的橫坐標(biāo)為i。一天,小B交給小A一個(gè)任務(wù),讓他降低自己家中的某些樹木的高度。這個(gè)任務(wù)對小A來說十分簡單,因?yàn)樗幸话褬O其鋒利的斧頭和一門獨(dú)門砍樹秘籍,能夠輕易地砍斷任何參天大樹。小A的砍樹方法有3種,都是沿著一條y=kx+b的直線砍一段區(qū)間的樹,相同的方法k值相同。只用了一個(gè)下午,小A就完成了小B的任務(wù)。第二天,小B來視察小A的任務(wù)完成情況。小B想知道小A是否真的用心砍樹,于是提出了q個(gè)詢問,每次詢問一段區(qū)間中最低的樹的高度。小A當(dāng)然是不會記住樹木的砍伐情況的,他只知道自己按什么順序,使用了什么方法,砍了哪個(gè)連續(xù)區(qū)間的樹,而且區(qū)間都是互不包含的。現(xiàn)在小A想請你幫幫他,回答小B的詢問。
輸入格式
第一行三個(gè)整數(shù)k1,k2,k3表示小A三種砍樹方法的斜率值;
第二行一個(gè)數(shù)n,表示一共有n棵樹;
第三行n個(gè)數(shù)hi,分別表示n棵樹的高度;
第四行一個(gè)數(shù)m,表示小A一共進(jìn)行了m次操作;
接下來m行,每行四個(gè)數(shù)L,R,p,b,表示用第p種方法,即用y=kp+b的直線砍[L,R]區(qū)間的樹;
接下來一行一個(gè)數(shù)q,表示小B的詢問數(shù);
接下來q行,每行兩個(gè)數(shù)L,R,表示詢問[L,R]區(qū)間中最低的樹的高度。
輸出格式
一共q行,每行一個(gè)數(shù)h表示對應(yīng)的回答。
樣例輸入
1 0 -1 4 10 30 20 1 2 3 4 2 5 1 3 3 10 2 1 2 2 3樣例輸出
8 5數(shù)據(jù)范圍
n<=1000000,m<=500000
空間限制 64MB
提示
如下圖,紅色即為樹的剩余部分。
解
注意到本題使用離線算法,而且直線的斜率只有三種。
所以先按左端點(diǎn)排序,然后直接用三個(gè)線段樹或單調(diào)隊(duì)列維護(hù)。
最后查詢時(shí)使用線段樹。(不能用ST表,否則MLE)
Code
#include<bits/stdc++.h> using namespace std; typedef long long D; const int maxn=1000003; struct QQ{int l,r,p;D b;bool operator <(const QQ &x)const{return l<x.l;} }q[maxn]; int n,Q; deque<QQ> deq[4]; D a[maxn],k[4],t[maxn<<2]; void build(int p,int l,int r){if(l==r){t[p]=a[l];return;}int mid=(l+r)>>1;build(p<<1,l,mid);build(p<<1|1,mid+1,r);t[p]=min(t[p<<1],t[p<<1|1]); } D query(int p,int l,int r,int seg_l,int seg_r){if(seg_l<=l&&r<=seg_r)return t[p];int mid=(l+r)>>1;if(seg_l<=mid&&seg_r>mid)return min(query(p<<1,l,mid,seg_l,seg_r),query(p<<1|1,mid+1,r,seg_l,seg_r));else if(seg_l<=mid)return query(p<<1,l,mid,seg_l,seg_r);else return query(p<<1|1,mid+1,r,seg_l,seg_r); } int main(){scanf("%lld%lld%lld%d",k+1,k+2,k+3,&n);for(int i=1;i<=n;i++)scanf("%lld",a+i);scanf("%d",&Q);for(int i=1;i<=Q;i++){scanf("%d%d%d%lld",&q[i].l,&q[i].r,&q[i].p,&q[i].b);q[i].r++;}sort(q+1,q+Q+1);for(int i=1,j=1;i<=n;i++){for(;j<=Q&&q[j].l<=i;j++){QQ qq=q[j];deque<QQ> &que=deq[qq.p];while(!que.empty()&&qq.b<=que.back().b)que.pop_back();que.push_back(qq);}for(int j=1;j<=3;j++){deque<QQ> &que=deq[j];while(!que.empty()&&que.front().r<=i)que.pop_front();if(!que.empty()){QQ res=que.front();a[i]=min(a[i],k[res.p]*i+res.b);}}}build(1,1,n);scanf("%d",&Q);while(Q--){int x,y;scanf("%d%d",&x,&y);printf("%lld\n",query(1,1,n,x,y));}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/BlogOfchc1234567890/p/11267683.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
- 上一篇: 关闭子页面刷新父页面,不需要弹出确认窗口
- 下一篇: AsyncTask应用解析