首页 > 其他分享 >AHOI,但是初中组,2017-2018

AHOI,但是初中组,2017-2018

时间:2022-12-26 11:24:27浏览次数:59  
标签:AHOI int mid sqrt define 2018 2017 include dis

你觉得我这种彩笔像是能去做省选题的样子吗?=w=

合肥人,做初中的屑安徽题,很正常吧。AH 也不知道为啥搞啥市赛啊区赛啊省赛啊就挺离谱的反正摆烂人也不想打┓( ´∀` )┏

2018

T1

签到题

//SIXIANG
#include <iostream>
#define MAXN 100000
#define LL long long
#define QWQ cout << "QWQ" << endl;
using namespace std;
int a[MAXN + 10];
int main() {
	int n; cin >> n;
	LL ans = 0;
	for(int p = 1; p <= n; p++)
		cin >> a[p];
	for(int p = 1; p < n; p++)
		ans += max(a[p], a[p + 1]);
	cout << ans << endl; 
}

T2

很棒的题捏,一开始没有想出来,然后试图用暴力卡常结果就几个 ms 卡不过去(捂脸

首先我们先考虑如果 \(x\) 是完全平方数怎么做(因为部分分给了=w=),显而易见直接二分。

那么我们再考虑 \(x\) 不是完全平方数的做法。我们考虑题目中的式子 \(x = a^3b\)。我们要尽力求出一个 \(b\),最后的剩下的 \(\dfrac{x}{b}\) 就二分跑一遍就可以了。我们考虑一下性质,如果我们 \(b\) 做一个唯一分解,那么它的次数都小于等于 \(2\)。同时 \(b\) 显然不可能大于 \(\sqrt[4]{x}\)。我们通过这两点会发现 \(b\) 里面所有质因子都不大于 \(\sqrt[4]{x}\)。因而可以把 \(b\) 表示为 \(b=pq^2\)。\(a\) 必然不超过 \(\sqrt[3]{x}\)。

然后是一个比较人类智慧的操作 \(x\) 除掉所有 \(\sqrt[4]{x}\) 里面的素数,剩下的要么然是立方数,要么是 \(a = 1\) 的数字。我感觉这么智慧的操作可能是因为“\(b\) 里面所有质因子都不大于 \(\sqrt[4]{x}\)”(或者说伟大的人类智慧)。如果我们除掉这些质因数,肯定把 \(b\) 里面的质因数都除掉了一次。那么 \(b\) 肯定没了。那 \(a\) 呢?\(a\) 小于等于 \(\sqrt[4]{x}\) 的因子全没了。如果 \(a\) 的所有引子都是小于 \(\sqrt[4]{x}\) 的,那么 \(a = 1\),否则 \(a\) 为立方数。

有了这个奇妙的引理,那么这道题就不难做了,首先把小于等于 \(\sqrt[4]{1e18}\)(差不多是 32000) 的素数预处理出来,然后对 \(x\) 除掉里面的素数,最后对剩下的 \(x'\) 二分求立方根。然后用原来的 \(x\) 逝世有没有小于等于 \(\sqrt[4]{1e18}\) 的立方质因子 awa。

这个引理比较人类智慧,不过也不太算,比较简单

//SIXIANG
#include <cstdio>
#include <cmath>
#define MAXN 32000
#define LL long long
#define int long long
#define QWQ cout << "QWQ" << endl;
using namespace std;
bool vis[MAXN + 10];
int pri[MAXN + 10], tot = 0;
void prime() {
	vis[1] = 1;
	for(int p = 2; p <= MAXN; p++)
		if(!vis[p]) {
			pri[++tot] = p;
			for(int i = p + p; i <= MAXN; i += p)
				vis[i] = 1;
		}
}
LL divide(LL x, LL lim) {
	for(int p = 1; p <= tot; p++) {
		if(pri[p] > lim) break;
		int cnt = 0; 
		while(x % pri[p] == 0) x /= pri[p];
	}
	return x;
}
LL sqrt3(LL x) {
	LL l = 1, r = 1e6, mid;
	while(l <= r) {
		mid = (l + r) >> 1;
		if(mid * mid * mid < x) l = mid + 1;
		else if(mid * mid * mid > x) r = mid - 1;
		else return mid; 
	}
	return 1;
}
signed main() {
	prime();
	LL x;
	int T; scanf("%lld", &T);
	while(T--) {
		scanf("%lld", &x);
		LL pk = 1;
		LL sqrt4 = ceil(sqrt(sqrt(x)));
		for(int p = 1; p <= tot; p++) {
			if((LL)pri[p] > sqrt4) continue;
			int cnt = 0;
			while(x % pri[p] == 0) {
				x /= pri[p];
				cnt++;
				if(cnt % 3 == 0)
					pk *= pri[p];
			}
		}
		printf("%lld\n", sqrt3(x) * pk);
	}
}

T3
签到题,模拟题。

先排序,然后挨个尝试加入队列,如果加不进去就新开一个队列,最后统计人数最少的队列。显而易见,这是对的,证明日后补吧 =w=

//SIXIANG
#include <iostream>
#include <algorithm> 
#include <queue>
#define MAXN 100000
#define QWQ cout << "QWQ" << endl;
using namespace std;
int a[MAXN + 10];
struct node {
	int back, siz;
} que[MAXN + 10];
int main() {
	int n; cin >> n;
	for(int p = 1; p <= n; p++)
		cin >> a[p];
	sort(a + 1, a + n + 1);
	int tot = 0;
	for(int p = 1; p <= n; p++) {
		bool homo = 0;
		for(int i = 1; i <= tot; i++) {
			if(que[i].back - a[p] == -1) {
				que[i].back = a[p];
				que[i].siz++;
				homo = 1;
				break;
			}
		}
		if(!homo) que[++tot].back = a[p], que[tot].siz = 1;
	}
	int minn = 0x7f7f7f7f;
	for(int p = 1; p <= tot; p++)
		minn = min(minn, que[p].siz);
	cout << minn << endl;
}

也可以用堆来优化到 O(nlogn),上面这个时间复杂度是玄学,最坏 $O(n^2)$,不过显然跑不满

T4
神仙题。

先考虑一下只有 \(1,2\) 的情况,这个时候必然是 \(1,2\) 交替的放,然后就显然对吧。

然后再考虑只有质数的情况,那么相邻两个必然不相同。那么我们的问题就是说有 \(n\) 个球然后每个球有个颜色相邻两个球颜色不同。

这个问题比现在这个题好做多了,但是我们先放在一边。

在考虑自然数的情况。我们考虑把它变成上面那个问题 \(n\le 300\),所以可以高一些好康的。

引理:如果 \(xy\) 为平方数,\(yz\) 为平方数,\(xz\) 也是平方数。
证明:显然把 =w=。

所以说我们可以枚举 \(i, j(i \not= j)\),如果 \(ij\) 为平方数,那么就并查集连一起,同一个并查集里面的看成一个颜色。

然后就可以愉快的 dp 啦~这才是本题最毒瘤的,zyf 巨佬说有某个合肥六中巨佬当年也卡在了这里所以我看题解不过分吧,心理平衡了(???

不难想到以颜色为阶段,设 \(f_i\) 为前 \(i\) 个颜色的合法方案数。但显然不行,因为合法方案可能由不合法的转移而来。所以我们加一维,\(f_{i, j}\) 代表前 \(i\) 个颜色 \(j\) 个相邻的数的方案。假设第 \(i\) 种颜色有 \(S_i\) 个球,每次转移会在其中新增 \(ad\) 个相邻数,抵消掉原来 \(su\) 个相邻数。转移到的状态就应该是 \(f_{i, j}\) 到 \(f_{i+1,j + ad - su}\)。

先考虑增加增加 \(ad\) 个相邻数。在

2017

T1
本来还以为是什么数学题,后来发现是暴力就没写了 =w=

T2
写了详细的题解link

T4

抄原题,太屑了。这 FJ 一看就是 USACO 的,安徽人很负责的(•́へ•́╬)

很显然吧,跑 2 遍 dij 求出来权值为 \(P\) 与权值为 \(Q\) 的图上的最短路,然后对每条边 \((u, v)\),统计不在多少张图的最短路上,就是边权。再跑一遍最短路。

然后如何判断 \((u, v)\) 在不在最短路上?很简单 \(dis_u + val = dis_v\) 就是在最短路上。

不过由于这里面最短路是指当前节点到终点的最短路,所以要反向建图

#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
#define MAXN 500000
using namespace std;
int k;
struct node {
    int to, val[2];
    node(int t, int p, int q) {
        to = t, val[0] = p, val[1] = q;
    }
    bool operator < (const node &other) const {
		return val[k] > other.val[k];
	}
};
vector <node> gra[MAXN + 10], ngr[MAXN + 10];
bool vis[MAXN + 10];
int dis1[MAXN + 10], dis2[MAXN + 10], dis3[MAXN + 10];
void Dijkstra(int s, int *dis) {
    for(int p = 1; p <= MAXN; p++)
        dis[p] = 0x7f7f7f7f;
    memset(vis, 0, sizeof(vis));
	priority_queue <node> que;
	que.push(node(s, 0, 0));
	dis[s] = 0;
	while(!que.empty()) {
		node fr = que.top(); que.pop();
		int u = fr.to;
		if(vis[u]) continue;
		vis[u] = 1;
		for(int p = 0; p < gra[u].size(); p++) {
			int v = gra[u][p].to;
			if(dis[u] + gra[u][p].val[k] < dis[v]) {
				dis[v] = dis[u] + gra[u][p].val[k];
				if(!vis[v])
                    if(k == 0) que.push(node(v, dis[v], 0));
                    else que.push(node(v, 0, dis[v]));
			}
		}
	}
}
int main() {
    int n, m;
    cin >> n >> m;
    for(int p = 1, x, y, P, Q; p <= m; p++) {
        cin >> y >> x >> P >> Q;
        gra[x].push_back(node(y, P, Q));
    }
    k = 0, Dijkstra(n, dis1);
    k = 1, Dijkstra(n, dis2);
    int yyy = 0;
    for(int u = 1; u <= n; u++) {
        for(int p = 0; p < gra[u].size(); p++) {
            int v = gra[u][p].to;
            if(dis1[v] != dis1[u] + gra[u][p].val[0]) yyy++;
            if(dis2[v] != dis2[u] + gra[u][p].val[1]) yyy++;
            ngr[u].push_back(node(v, yyy, 0));
            yyy = 0;
        }
    }
    for(int p = 1; p <= n; p++)
        for(int i = 0; i < ngr[p].size(); i++)
            gra[p][i] = ngr[p][i];
    k = 0, Dijkstra(n, dis3);
    cout << dis3[1] << endl;
}

标签:AHOI,int,mid,sqrt,define,2018,2017,include,dis
From: https://www.cnblogs.com/thirty-two/p/16863162.html

相关文章

  • Visual Studio 2017(vs2017)绿色便携版-北桃特供
    原版的VisualStudio2017有几十G,安装起来特别慢,不少用户叫苦连天。该版本是精简过的vs2017,且简化了原来的安装程序,特别适用于教学、个人开发者、某些要求不高的企业。该绿......
  • AT_jag2018summer_day2_a 10^N+7 题解
    题目传送门题目大意有三个非负整数$x,y,z$,找到符合以下条件的最小非负整数\(n\);$n\{\rm\mod}\10^1+7\=\x$$n\{\rm\mod}\10^2+7\=\y$$n\{\rm\mo......
  • AT_mujin_pc_2018_b セキュリティ 题解
    题目传送门题目大意房间原有\(A\)人,+表示进来一个人,-表示出去一个人;求是否有一个时间,房间内的人数为\(0\)。解题思路按题意进行模拟:首先判断\(A\)是否等于零,......
  • 基于OpenVINO的端到端DL网络-Tesseract5+VS2017+win10源码编译攻略
    一,记录我目前在win10X64和VS2017的环境下成功编译Tesseract5.0的方式;二,记录在VS2017C++工程中调用Tesseract4.0的方法;三,记录编译和调用Tesseract4.0过程中踩到的坑和相......
  • AT_pakencamp_2018_day2_a ひふみ (Hihumi) 题解
    题目传送门题目大意从\(1\)到\(N\)数数的时候,会数几个整数呢(除123外)?解题思路如果\(N\)小于123,就不会数到123,所以数了\(N\)次。否则,就会数到123,所以数的......
  • luogu P4775 [NOI2018] 情报中心
    题面传送门牛逼题,第一步转化都想不到。首先题目要求的是选出两条路径\((x_1,y_1),(x_2,y_2)\)满足有交,并且并的部分减去\(w_1+w_2\)最大。不妨假设\(p_1\)是\(x_1\)与\(......
  • 2017-2020年世界各国GDP数据爬取
    2017-2020年世界各国GDP数据爬取一二三四五总分      一、选题的背景通过爬取2017-2020年世界各国历年来的GDP数据,......
  • whctf2017_note_sys
    whctf2017_note_sys最近太颓废了,zikh师傅上南京参加比赛了恭喜获得第五名,我太菜了,只能膜拜大佬。><,在学习一下vmpwn吧,正好zikh师傅写的一篇保护漏洞利用主要就是利......
  • P7312 [COCI2018-2019#2] Sunčanje
    想要使第i个矩形覆盖第j个矩形,必须满足:$i>j$$x1_i\lex2_j$&&$x1_j\lex2_i$$y1_i\ley2_j$&&$y1_j\ley1_i$第一个条件可以直接排序。考虑使用cdq分治完......
  • P5298 [PKUWC2018]Minimax
    题解\(f_{u,k}\)节点\(u\)是第\(k\)小的点的概率。\(deg=2\)的情况:\[f_{u,k}=(1-p_u)\left(f_{lc,k}\sum_{k'>k}f_{rc,k'}+f_{rc,k}\sum_{k'>k}f_{lc,k'}+f_{lc......