Place for a Selfie:
题意:
给你n个过原点的直线和m个抛物线,对每一条抛物线求是否存在一条直线不和其相交。
思路:
连立方程组:kx=ax^2+bx+c;
若抛物线与直线不相交则(b-k)^2-4ac<0;
所以我们只需要使b-k的绝对值最小即可,也就是二分查找一下距离b最近的两个k(分别是大于等于b的和小于等于b的),如果这个k无法使(b-k)^2-4ac<0,那么输出NO,否则就输出yes;
考点:二分
代码:
#pragma GCC optimize(2)
#include <iostream>
#include <vector>
#include <queue>
#include <bitset>
#include <map>
#include <cstring>
#include <set>
#include <algorithm>
#define endl "\n"
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
using namespace std;
const int N=100100;
typedef long long LL;
typedef unsigned long long ULL;
const LL inf=0x3f3f3f3f3f3f3f3f;
LL dt(LL b,LL k,LL a,LL c){
if((b-k)*(b-k)<4*a*c) return -1;
else return 1;
}
bool cmp(LL a,LL b){
return a>b;
}
LL sz[N];
int main(){
quick_cin();
LL t;
cin>>t;
while(t--){
LL n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>sz[i];
}
sort(sz,sz+n);
for(int i=0;i<m;i++){
LL a,b,c;
cin>>a>>b>>c;
int flag=0;
if(c<=0){
cout<<"NO\n";
}
else{
LL x=lower_bound(sz,sz+n,b)-sz;
LL x1=x-1;
//cout<<x<<"- "<<x1<<endl;
if(dt(b,sz[x],a,c)<0&&x<n&&x>=0){
flag=1;
cout<<"YES\n";
cout<<sz[x]<<endl;
}
if(dt(b,sz[x1],a,c)<0&&flag==0&&(x<n||sz[x1]<b)&&x1>=0){
flag=1;
cout<<"YES\n";
cout<<sz[x1]<<endl;
}
if(flag==0) cout<<"NO\n";
}
}
}
return 0;
}
比赛的时候因为快输卡了好久,真的修的头都炸了。
A Wide, Wide Graph
题意:
给定一颗树,每边的权值为1,要求根据距离重置边,距离大于等于k的两点之间链接一条无向边,问当k={1.....n}时有多少联通块
思路:
先给出一个结论:在树中如果某个点距离其他点最长边为k那么他和其他所有最长边>=k的点都在一个联通集里,并且所有最长边<k的点都是孤立的。
那么答案就很显然了,维护一个最长边长度的后缀和ans1 答案就是
if(ans1[k]>0)cout<<(n-ans1[k]+1)<<" ";
else cout<<n<<" ";
然后维护用dijkstra和树的直径扫一遍就好了
树的直径:
树上的最远的两点之间的路径。
维护树的直径的方法:随机选一个点走一遍dijkstra最长路,那么最远的那个点就是树的直径的一端(flag),再从找到的这一端出发走一遍dijkstra就能找到另一端(flag),然后再从flag走一遍dijkstra就能找到所有点的最长边(ans[])
代码:
#pragma GCC optimize(2)
#include <iostream>
#include <vector>
#include <queue>
#include <bitset>
#include <map>
#include <cstring>
#include <set>
#include <algorithm>
#define endl "\n"
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
using namespace std;
const int N=300100;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
const LL inf=0x3f3f3f3f3f3f3f3f;
int n;
int fa[N];
int idx,h[N],e[N],ne[N];
int dist[N];
int ans[N];
int ans1[N];
bool st[N];
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void dijkstra(int x){
memset(st,0,sizeof st);
memset(dist,0,sizeof dist);
priority_queue<PII,vector<PII>,less<PII> > q;
q.push({0,x});
dist[x]=0;
while(q.size()){
int t=q.top().second;
q.pop();
if(st[t])continue;
st[t]=1;
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]<dist[t]+1&&st[j]==0){
dist[j]=dist[t]+1;
q.push({dist[j],j});
}
}
}
}
int main(){
//quick_cin();
memset(h,-1,sizeof h);
cin>>n;
for(int i=0;i<n-1;i++){
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
dijkstra(1);
int maxl=0,flag=0;
for(int i=1;i<=n;i++){
if(maxl<dist[i]){
maxl=dist[i];
flag=i;
}
ans[i]=dist[i];
}
dijkstra(flag);
maxl=0;
for(int i=1;i<=n;i++){
if(maxl<dist[i]){
maxl=dist[i];
flag=i;
}
ans[i]=max(dist[i],ans[i]);
}
dijkstra(flag);
for(int i=1;i<=n;i++){
if(maxl<dist[i]){
maxl=dist[i];
flag=i;
}
ans[i]=max(dist[i],ans[i]);
ans1[ans[i]]++;
}
for(int i=n-1;i>0;i--){
ans1[i]+=ans1[i+1];
}
for(int i=1;i<=n;i++){
if(ans1[i]>0)cout<<(n-ans1[i]+1)<<" ";
else cout<<n<<" ";
}
return 0;
}
为了修那个c题没来及做,我真的,受不了啦!!!!!!