小红的最大价值
定义一个数对的 ai,aj,i<ja_i, a_j, i < jai,aj,i<j 的价值为:如果 ∣ai−aj∣>k|a_i - a_j| > k∣ai−aj∣>k,则价值为 max(ai,aj)\max(a_i, a_j)max(ai,aj),否则价值为 min(ai,aj)\min(a_i, a_j)min(ai,aj)。
#include<bits/stdc++.h>
using namespace std;
int main(){
int M1 = 0, m1 = 1e9;
int n, k;
cin >> n >> k;
vector<int> a(n);
for(int i = 0; i < n; i ++)
cin >> a[i];
sort(a.begin(), a.end());
if(abs(a[n - 1] - a[0]) > k)
cout << a[n - 1];
else
cout << a[n - 2];
return 0;
}
小红的约数
对于一个正整数 nnn 和一个非负整数 ddd,定义 fd(n)f_d(n)fd(n) 为 nnn 的所有约数的 ddd 次方之和。如 f3(10)=13+23+53+103f_3(10) = 1^3 + 2^3 + 5^3 + 10^3f3(10)=13+23+53+103。
由于 nnn 可能很大,所以给出 nnn 的质因数分解式。
n=∏i=1wpiain = \prod_{i = 1}^w p_i^{a_i}n=∏i=1wpiai
第一行输入一个正整数 www 和一个非负整数 ddd。
接下来 www 行,每行输入两个正整数 pi,aip_i, a_ipi,ai。
保证 pip_ipi 为素数且互不相同。
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
// 快速幂算法
long long Pow(long long a, long long b) {
long long res = 1;
while (b) {
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b = b >> 1;
}
return res;
}
// 使用几何级数公式计算 p^(0*d) + p^(1*d) + ... + p^(a*d)
long long sumOfPowers(long long p, long long a, long long d) {
if (d == 0) {
// d 为 0 时,所有的次方都是 1,总和为 a+1
return (a + 1) % mod;
}
long long p_d = Pow(p, d);
if (p_d == 1) {
// 如果 p^d == 1, 那么所有的次方都是 1,总和为 a+1
return (a + 1) % mod;
}
// 几何级数和公式
long long numerator = (Pow(p_d, a + 1) - 1 + mod) % mod;
long long denominator = (p_d - 1 + mod) % mod;
long long denominator_inv = Pow(denominator, mod - 2);
return numerator * denominator_inv % mod;
}
int main() {
int w, d;
cin >> w >> d;
vector<pair<long long, long long>> factors(w);
for (int i = 0; i < w; i++) {
cin >> factors[i].first >> factors[i].second;
}
long long res = 1;
for (auto [p, a] : factors) {
long long sum_powers = sumOfPowers(p, a, d);
res = res * sum_powers % mod;
}
cout << res << endl;
return 0;
}
小红的图上划分
小红有一个无向图,有 nnn 个点 mmm 条边。小红有 qqq 个询问,每次给出 L,RL, RL,R,求将图划分为至少 LLL 个连通块,最多 RRR 个连通块的最大划分价值,若不可划分输出 "NO ANSWER"。
图的划分定义为将图划分为一个或多个连通块,对于每个连通块,其点集为其边集中每一条边的两端点的集合,且点集内任意两点均可通过边集里的边互相到达。
划分价值定义为所有连通块边集中的最小边权。
#include<bits/stdc++.h>
using namespace std;
//#define ONLINE
#ifndef ONLINE
#define debug(...) fprintf(stderr,##__VA_ARGS__)
#else
#define debug(...) ;
#endif
using LL=long long;
using PII=pair<int,int>;
#define all(x) (x).begin(),(x).end()
#define allr(x) (x).rbegin(),(x).rend()
template<typename T>
inline T READ(){
T x=0; bool f=0; char c=getchar();
while(!isdigit(c)) f|=(c=='-'),c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return f?-x:x;
}
inline int read(){return READ<int>();}
inline LL readLL(){return READ<LL>();}
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
#define N 200010
int fa[N];
int g(int u){
return u==fa[u]?u:fa[u]=g(fa[u]);
}
void solve(){
int n=read(),m=read(),T=read();
vector<array<int,3>>e(m);
for(int i=0;i<m;i++){
e[i][0]=read(),e[i][1]=read(),e[i][2]=read();
}
sort(all(e),[&](const auto& A,const auto& B)->bool{
return A[2]>B[2];
});
iota(fa+1,fa+n+1,1);
vector<int>a(n+1,INT_MAX);
int rest=n;
for(auto [u,v,w]:e){
int U=g(u),V=g(v);
if(U==V) continue;
a[--rest]=w;
fa[U]=V;
}
for(int l,r;T--;){
l=read(),r=read();
if(a[r]==INT_MAX) printf("NO ANSWER\n");
else printf("%d\n",a[r]);
}
}
int main(){
solve();
return 0;
}
/* stuff you should look for
* int overflow, array bounds
* special cases (n=1?)
* do smth instead of nothing and stay organized
* WRITE STUFF DOWN
* DON'T GET STUCK ON ONE APPROACH
*/
小红的白点距离
小红有一棵树,初始所有点都是白色。小红最多可以染黑 kkk 个点,定义染色后树的权值为白色点对距离的最大值,求最小的权值。
/*
首先N^2
预处理所有点对距离
然后二分答案
问题变成N^2判断
给定m条边
是否可以选出最多k个点
使得每条边都有至少一个端点被覆盖
最小点覆盖问题?
像个傻子
显然倒过来
本质上就是让你在原图上选出若干个白点,使得两两最大距离最小
这TM显然是一个连通块
所以再次二分答案
钦定连通块最长不超过mid
是否可能选出一个大小>=n-k的连通块
设f[u,k]:子树u选出k个点,在满足直径不超过mid的情况下
其最短的链长是多少
改一下
我们枚举这个连通块的某个边缘节点
也就是根
不了
我们就用:
f[u,k]:最长深度为k时,最多选出点数
f'[u,max(p,q)]=f[u,p]+f[v][q],p+q<=mid
*/
#include<bits/stdc++.h>
using namespace std;
#define N 1050
int read(){
int x=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0')w=(ch=='-'?-w:w),ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*w;
}
void print(int x){
if(x<0)putchar('-'),print(-x);
else if(x<10)putchar('0'+x);
else print(x/10),putchar(x%10+'0');
}
vector<int>e[N];
int mid,g[N],f[N][N],siz[N],mx=0;
void dfs(int u,int fa){
f[u][0]=1;siz[u]=1;
for(auto v:e[u]){
if(v==fa)continue;
dfs(v,u);
for(int i=0;i<=siz[u];i++)for(int j=0;j<=siz[v];j++){
if(!f[u][i])continue;if(!f[v][j])continue;
if(i+j+1<=mid)g[max(i,j+1)]=max(g[max(i,j+1)],f[u][i]+f[v][j]);
}
siz[u]+=siz[v];
for(int i=0;i<=siz[u];++i)f[u][i]=max(f[u][i],g[i]),g[i]=0;
}
// cout<<u<<": ";
// for(int i=0;i<=siz[u];i++)cout<<f[u][i]<<" ";cout<<"\n";
for(int i=0;i<=siz[u];i++)mx=max(mx,f[u][i]);
}
int main(){
int n=read(),k=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].push_back(v);e[v].push_back(u);
}
int l=1,r=n;
while(l<r){
mid=l+r>>1;mx=0;
// cout<<mid<<"!\n";
memset(f,0,sizeof f);
dfs(1,0);
if(mx>=n-k)r=mid;
else l=mid+1;
}
cout<<l<<"\n";
}