2018.9.3模拟赛

\(T1\)
直接考虑二分就可以了。。。
二分spfa判断,直接AC一发!

#include<bits/stdc++.h>
using namespace std;
struct edge{
	int to,nxt;
	double val;
} e[400010];
int	l1,l2,r1,r2,xz,n,m,cnt = 0,head[50010],fa[50010],u[200010],v[200010],x[5010],dis[50010],vis[50010],s,t,que[200010],w[200010];
double	l = 15000,r;
inline int read (){
	int q=0,f=1;char ch = getchar();
	while(!isdigit(ch)) {
		if(ch=='-')f=-1;ch=getchar();
	}
	while(isdigit(ch)){
		q=q*10+ch-'0';ch=getchar();
	}
	return q*f;
}
inline double minn(double a,double b)
{
	if (a < b) return a; else return b; 
}
inline double maxx(double a,double b)
{
	if (a > b) return a; else return b;
}
inline void add(int a,int b,double c)
{
	e[++cnt].to = b;
	e[cnt].val = c;
	e[cnt].nxt = head[a];
	head[a] = cnt;
}
inline bool Spfa(int xx)
{
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	int ll = 0,rr = 1;
	que[1] = s;
	vis[s] = 1;
	dis[s] = 0;
	while (ll < rr)
	{
		ll ++;
		int u = que[ll];
		vis[u] = 0;
		for (int i = head[u]; i ; i = e[i].nxt)
		{
			if (e[i].val >= xx && dis[e[i].to] > dis[u] + 1)
			{
				dis[e[i].to] = dis[u] + 1;
				if (!vis[e[i].to])
				{
					rr ++;
					que[rr] = e[i].to;
					vis[e[i].to] = 1;
				}
			}
		}
	}
	if (dis[t] != 0x3f3f3f3f) return 1; else return 0;
}
inline bool Spfaa(int xx)
{
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	int ll = 0,rr = 1;
	que[1] = s;
	vis[s] = 1;
	dis[s] = 0;
	while (ll < rr)
	{
		ll ++;
		int u = que[ll];
		vis[u] = 0;
		for (int i = head[u]; i ; i = e[i].nxt)
		{
			if (e[i].val  <= xx && e[i].val >= l1 * 1.000 && dis[e[i].to] > dis[u] + 1)
			{
				dis[e[i].to] = dis[u] + 1;
				if (!vis[e[i].to])
				{
					rr ++;
					que[rr] = e[i].to;
					vis[e[i].to] = 1;
				}
			}
		}
	}
	if (dis[t] != 0x3f3f3f3f) return 1; else return 0;
}
int main()
{
	freopen("trip.in","r",stdin);
	freopen("trip.out","w",stdout);
	n = read();
	m = read();
	for (int i = 1; i <= m; i ++)
	{
		u[i] = read();
		v[i] = read();
		w[i] = read();
	}
	for (int i = 1; i <= n; i ++)
	{
		int num = read();
		for (int j = 1; j <= num; j ++)
		{
			fa[read()] = i;
		}
	}
	for (int i = 1; i <= n; i ++)
	{
		x[i] = read();
	}
	s = read();
	t = read();
	for (int i = 1; i <= m; i ++)
	{
		double ww = w[i] * (x[fa[u[i]]] + x[fa[v[i]]]) * 1.000 / 200;
		add(u[i],v[i],ww);
		add(v[i],u[i],ww);
		l = minn(l,ww);
		r = maxx(r,ww);
	}
	l1 = l;
	l2 = l;
	r1 = r;
	r2 = r;
	if (r1 - r != 0) 
	{
		r1 ++;
		r2 ++;	
	} 
	//cout<<l1<<' '<<r1<<endl;
	while (l1 < r1)
	{
		int mid = (l1 + r1) >> 1;
		if (Spfa(mid)) l1 = mid + 1; else r1 = mid;
		//cout<<l1<<' '<<r1<<endl;
	}
	while (!Spfa(l1)) l1 --;
	l2 = l1;
	while (l2 < r2)
	{
		int mid = (l2 + r2) >> 1;
		if (Spfaa(mid)) r2 = mid; else  l2 = mid + 1;
	}
	while (!Spfaa(l2)) l2 ++;
	printf("%d %d",l1,l2);
	return 0;
}

\(T2\)
推式子题。。。其实如果不想推的话可以直接高精。。。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 4010;
const int maxm = 100010;
inline int read (){
	int q=0,f=1;char ch = getchar();
	while(!isdigit(ch)) {
		if(ch=='-')f=-1;ch=getchar();
	}
	while(isdigit(ch)){
		q=q*10+ch-'0';ch=getchar();
	}
	return q*f;
}
const int lim = 100000000;
char s[100010];
int n,k;
int kth[maxm];
ll a[maxn];
bool vis[maxm];
int cnt = 1;
int main () {
	freopen("array.in","r",stdin);
	freopen("array.out","w",stdout);
	n = read();scanf("%s",s);
	int l = 4000;
	int len = strlen(s);
	for(int i = len - 1;i >= 0; --i) {
		a[l] += (s[i] - '0') * cnt;
		cnt = (cnt<<3) + (cnt << 1);
		if(cnt == lim) l--,cnt = 1;
	}
	int tmp;
	for(tmp = 4000;a[tmp] == 0;a[tmp] = lim - 1,tmp--);
	--a[tmp];
	for(int i = 1;i <= n; ++i) {
		for(int j = l;j < 4000; ++j) {
			ll x = a[j] / i;
			a[j + 1] += lim*(a[j] - x * i);
			a[j] = x;
		}
		kth[n - i + 1] = a[4000] % i + 1;
		a[4000]/=i;
		while(a[l] == 0)  ++l;
	}
	int mx = max(0,n - 6100);
	for(int i = 1;i <= mx; ++i) {
		printf("%d ",i);
	}
	for(int i = mx + 1;i <= n; ++i) {
		int j,tot;
		for(j = mx + 1,tot = 0;tot < kth[i]; ++j) {
			if(!vis[j]) ++tot;
		}
		vis[--j] = 1;
		printf("%d ",j);
	}
	return 0;
} 

\(T3\)

照样推式子,然后枚举约数就可以了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100];
ll p[100];
ll n;
ll d[3000010];
ll cnt;
ll N;
inline ll read (){
	ll q=0,f=1;char ch = getchar();
	while(!isdigit(ch)) {
		if(ch=='-')f=-1;ch=getchar();
	}
	while(isdigit(ch)){
		q=q*10+ch-'0';ch=getchar();
	}
	return q*f;
}
inline void dfs(ll now,ll x) {
	if(now > cnt) {
		if(x < N && !(N - x & 1) && ( N - x >> 1) % x == 0) d[++d[0]] = N - x;
		return;
	}
	ll T = 1;
	for(int i = 0;i <= p[now]; ++i) {
		dfs(now + 1,x * T);
		T *= a[now];
	}
}
int main () {
	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	n = read();
	N = n;
	if(n == 1) {
		return puts("0");
	}
	for(ll i = 2;i * i <= n; ++i) {
		if(!(n % i)) {
			n /= i;a[++cnt] = i;
			p[cnt] = 1;
			while(!(n % i)) n /= i,++p[cnt];
		}
	}
	if(n > 1) {
		a[++cnt] = n;
		p[cnt] = 1;
	}
	dfs(1,1);
	sort(d+1,d+d[0] + 1);
	printf("%d ",d[0]);
	for(int i = 1;i <= d[0]; ++i) {
		printf("%d ",d[i]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/akoasm/p/9577928.html