B. Anton and Lines
思路:
画个图就明白了,在区间 [x1,x2] 之间如果两条线段有交点,那么必定有下面的关系,所以我们可以求出所有直线上横坐标为 x1 和 x2 的点的纵坐标记为 L,R ,然后排一下序最后查找是否存在 L 教大但是
R 较小就OK了!怎么做呢?直接扫一遍加判断就好了。而且直接判断 p[i].SD<p[i−1].SD 就行了,想想为什么!
另:注意爆long long的问题!
代码:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <string>
#define PB push_back
#define FT first
#define SD second
#define MP make_pair
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<LL,LL> P;
const int maxn=10+1e5,MOD=7+1e9;
P p[maxn];
bool cmp(P a,P b)
{
if(a.FT == b.FT) return a.SD < b.SD;
return a.FT < b.FT;
}
int main()
{
int n;
int x1,x2;
scanf("%d%d%d",&n, &x1, &x2);
for(int i=0;i<n;i++){
int k,b;
scanf("%d%d",&k,&b);
p[i].FT = 1LL*x1*k + b;
p[i].SD = 1LL*x2*k + b;
}
sort(p,p+n,cmp);
bool ok=0;
for(int i=1;i<n;i++){
if(p[i].SD < p[i-1].SD) {
ok=1;
break;
}
}
if(ok) puts("YES");
else puts("NO");
return 0;
}
D. Happy Tree Party
思路:
对于从 a ->
b 的路径,如果边权值为1,则值不变,否则就是 1≤ 边权值,这样的话最多除64次就为0也就不需要继续除下去了,所以问题的关键在于去压缩哪些连续的边权为1的路径,这里自然就想到并查集啦,具体实现看代码吧!
另:因为更改后的边权值只会变小,所以只会涉及到集合并和查的操作。这一点要想懂。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define PB push_back
#define MP make_pair
#define FT first
#define SD second
using namespace std;
const int N = 10+2e5;
typedef pair<int,int> PII;
typedef long long LL;
int n, m;
int dep[N], st[N];
LL w[N];
vector<PII> G[N];
PII pre[N];
void dfs(int u,int fa)
{
dep[u] = dep[fa]+1;
for(int i = 0;i < G[u].size();i ++) {
int v = G[u][i].FT;
int id = G[u][i].SD;
if(v == fa) continue;
pre[v] = MP(u,id);
dfs(v,u);
}
}
int find_set(int u)
{
if(w[pre[u].SD] != 1) return u;
if(st[u] == u)
return st[u] = find_set(pre[u].FT);
return st[u] = find_set(st[u]);
}
int jmp(int a,LL &v)
{
int id = pre[a].SD;
if(w[id] > 1) {
v /= w[id];
return pre[a].FT;
}
return st[a] = find_set(st[a]);
}
LL cal(int a,int b,LL v)
{
while(v && a!=b) {
if(dep[a] < dep[b]) swap(a,b);
a = jmp(a,v);
}
return v;
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d%d",&n, &m);
for(int i = 1;i < n;i ++) {
int u,v;
scanf("%d%d%I64d",&u,&v,&w[i]);
G[u].PB(MP(v,i)), G[v].PB(MP(u,i));
}
dfs(1,0);
for(int i = 1;i <= n;i ++) st[i] = i;
while(m --){
int tp;
scanf("%d",&tp);
if(tp == 1) {
int a, b;
LL y;
scanf("%d%d%I64d",&a, &b, &y);
printf("%I64d\n",cal(a,b,y));
}
else {
int p;
LL c;
scanf("%d%I64d",&p, &c);
w[p] = c;
}
}
return 0;
}