1. 程式人生 > >【NOIP2018模擬10.27】總結

【NOIP2018模擬10.27】總結

真是一場養生比賽。 不得不說我識別水題的能力還是比較強的,T3一道裸的主席樹秒切了,T2暴力分十分良心,T1暴力只有10分。還是很後悔,這種結論題我總是懶得去推,結果少了別人90,以後還是要保持冷靜思考吧。

T1

T1 Constraints 首先你得把題看懂。 對於一個nn的排列,它的貢獻就是將它交換有序的最少次數。 我們可以設fif_i表示前ii個數所有方案的貢獻,那麼考慮ii放在哪一位。 直接放在第ii位,無需交換,只用加上fi1f_{i-1}。 如果不放在第ii位,我們就要把ii換到第ii位,貢獻一次。不放第ii位就有i1i-1种放法,另外i1i-1個數的排列是(i

1)!(i-1)!,所以一共有(i1)(i1)!(i-1)(i-1)!種方案貢獻是11,此外另外i1i-1個數也要交換,產生貢獻(i1)fi1(i-1)f_{i-1}

於是得到遞推式: fi=ifi1+(i1)(i1)!f_i=if_{i-1}+(i-1)(i-1)! 然後求逆元除以n!n!就行了。 預處理階乘和fnf_n,複雜度O(n)O(n),回答每次O(1)O(1)

Code:

#include <cstdio>
#include
<cstring>
#include <cstdlib> const int P = 998244353, N = 1e7 + 7; int pow(int a, int b) { int ret = 1; while (b) { if (b & 1) ret = 1ll * ret * a % P; a = 1ll * a * a % P, b >>= 1; } return ret; } int T, n, f[N], fac[N]; int main() { //freopen("inverse.in", "r", stdin);
//freopen("inverse.out", "w", stdout); f[1] = 0, fac[1] = 1; for (int i = 2; i <= N - 7; i++) f[i] = (1ll * i * f[i - 1] % P + 1ll * (i - 1) * fac[i - 1] % P) % P, fac[i] = 1ll * fac[i - 1] * i % P; scanf("%d", &T); while (T--) { scanf("%d", &n); printf("%d\n", 1ll * f[n] * pow(fac[n], P - 2) % P); } fclose(stdin); fclose(stdout); return 0; }

T2

這題真™暴力。 T2Constraints 資料範圍是亮點。

60%60\%的資料(莫名其妙拿了70pts70pts,出題人人真好): 考慮到nn只有600600k\sum k只有1000010000,容易想到一種O(nk)O(n\sum k)優秀 做法。 首先O(n3)O(n^3)預處理出每個點兩兩之間的最短路,Then對於每個詢問,在桶裡標記一下滿足條件的點,就OK了。

100%100\%的資料,要用bitset這個自帶132\frac{1}{32}常數的黑科技。 bitset可以理解為一個每一位只能是0或1的陣列,但是因為它經過壓位,時空複雜度都是O(n/32)O(n/32),其中nn是陣列位數。我們可以利用這個黑科技做這題。 開一個bitset<N> b[N][N],其中b[i][j]存的是與i距離<=j的點集。由於與i距離<=j的點集不太方便求,我們可以先考慮求與i距離=j的點集,然後用字首和的方式求出與i距離<=j的點集。 然後每次詢問把所有點對應的bitset取個並集,集合大小就是答案了。 求最短路的過程用bfs複雜度是O(n(n+m))=O(n2+nm)O(n(n+m))=O(n^2+nm)。吸了氧跑的還挺快,總的詢問是k\sum k,一次詢問複雜度是O(n/32)O(n/32),時間複雜度就是O(nk32)O(\frac{n\sum k}{32}),空間複雜度是O(n232)O(\frac{n^2}{32}),再加上O2STL的定製優化,就過了。 Tips:由於重邊較多,使用vector存邊貌似能更快。

Code:真的暴力

#include <bitset>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;

const int N = 1e3 + 7;
inline int read()
{
	int x = 0, f = 0;
	char c = getchar();
	for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = 1;
	for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ '0');
	return f ? -x : x;
}

int n, m, q;

vector<int> edge[N];
void add(int u, int v) { edge[u].push_back(v); }

int head, tail, que[N], d[N];
bitset<N> b[N][N], tmp;

void init()
{
	n = read(), m = read(), q = read();
	for (int i = 1, u, v; i <= m; i++) u = read(), v = read(), add(u, v), add(v, u);
	for (int i = 1; i <= n; i++)
	{
		memset(d, 0, sizeof(d));
		d[i] = 1, head = 1, que[tail = 1] = i;
		while (head <= tail)
		{
			int u = que[head++], siz = edge[u].size();
			for (int i = 0; i < siz; i++)
				if (!d[edge[u][i]])
					d[edge[u][i]] = d[u] + 1, que[++tail] = edge[u][i];
		}
		for (int j = 1; j <= n; j++) if (d[j]) b[i][d[j] - 1][j] = 1;
		for (int j = 1; j <= n; j++) b[i][j] |= b[i][j - 1];
	}
}

void solve()
{
	for (int i = 1; i <= q; i++)
	{
		int k = read();
		tmp.reset();
		for (int j = 1, x, y; j <= k; j++) x = read(), y = read(), tmp |= b[x][y];
		printf("%d\n", tmp.count());
	}
}

int main()
{
	//freopen("input", "r", stdin);
	//freopen("center.in", "r", stdin);
	//freopen("center.out", "w", stdout);

	init();
	solve();

	fclose(stdin);
	fclose(stdout);
	return 0;
}

T3

這題沒穿衣服(真裸)。 T3 Constraints 看到區間第kk大,首先會想到主席樹。可是看到新增與刪除操作,就做不了了嗎?不,偉大的shehui主義主席樹是無所不能的 。 由於是在序列左端修改,我們可以考慮倒著建主席樹,對於刪除操作,我們只需要把該位置對應的主席樹全部清空掉,由於一棵主席樹新增的節點最多就O(logn)O(logn)個,這個操作複雜度是O(logn)O(logn)的。插入操作就新建一棵主席樹,查詢操作就開個指標記錄一下我插入到了哪裡,找到實際要查詢的區間求行了。

我的清空方法比較暴力,就是樹上所有的節點左兒子右兒子都賦為0。最好離散化一下,這樣時間空間都會小很多,總複雜度O((n+q)log2(n+q))O((n+q)log_2(n+q))

Code:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int N = 4e5 + 7, Q = 2e5 + 7;
inline int read()
{
	int x = 0, f = 0;
	char c = getchar();
	for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = 1;
	for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ '0');
	return f ? -x : x;
}

int n, q, pt, a[N], tmp[N];
int opt[Q], L[Q], R[Q], K[Q];
int len, arr[N];

int tot, root[N], lson[N * 50], rson[N * 50], sum[N * 50];
void clear(int rt, int l, int r, int po)
{
	sum[rt]--; //這句貌似可以不加
	if (l 
            
           

相關推薦

NOIP2018模擬10.27總結

真是一場養生比賽。 不得不說我識別水題的能力還是比較強的,T3一道裸的主席樹秒切了,T2暴力分十分良心,T1暴力只有10分。還是很後悔,這種結論題我總是懶得去推,結果少了別人90,以後還是要保持冷靜思考吧。 T1 首先你得把題看懂。 對於一個nnn的排列,它

JZOJ5932. NOIP2018模擬10.27情報中心

傳送門 preface   這道題資料超級水,暴力70。正解也超級玄學,需要各種卡常技巧。 分析   首先看資料範圍,貌似O(k)才能過廢話。既然是要O(k)的出答案,那就只能預處理了。   設f[i][j][k]表示以第i好結點為起點,在最短距離不超過j的情況下,是否能到達k號結點。對於這樣的東西

JZOJ 5931. NOIP2018模擬10.27氣泡排序

題目 求一個n的全排列的變成 1…n的序列 期望最少交換次數。 題解 實在想不出來,可以找規律。 其實這題不需要找規律。 方法1 第一類斯特林數靈感? hzj的第一題,序列前n-1個元素只能夠與第n個交換,想到一圈一圈地換。 這裡也是類似的,只不過任意兩個元素都可以交

JZOJ 5932. NOIP2018模擬10.27情報中心

題目 給定一個點數為n個圖,m條邊。 走一條邊算1步。 共有q個詢問 每個詢問中有k個點,求有多少個點可以走最多v步走到詢問中的任意一個點。 資料範圍 n

JZOJ 5933. NOIP2018模擬10.27百鴿籠

題目 鴿鴿鴿 有一個序列,有3種操作。 ①刪除最左邊的元素 ②在序列的最左邊加入一個數。 ③查詢序列中第l個數到第r個數中第k小的數。 題解 想到之前ifk通過動態樹最終狀態的dfs序將問題轉化成靜態樹問題,我打算也用類似的方法。 其實不需要。 每次刪除和插入的都是最左邊的

JZOJ5933. NOIP2018模擬10.27百鴿籠

題目 在JOU管理員群裡一共有n(n≤200000)個管理員,為了容納這些管理員,vfk準備了n個鴿籠。每個 鴿籠中都裝有一個咕咕能力值為vi的鴿子,每隻鴿子能力值不一定相同。每當RU開始或結束或 咕咕咕時,管理員們就會對這些鴿籠進行操作。操作包括三種: 1 vfk和管理員們取出最左端的

JZOJ-senior-5933. NOIP2018模擬10.27百鴿籠

Time Limits: 2000 ms Memory Limits: 262144 KB Description Input 從檔案 pigeon.in 中讀入資料。 輸入第一行包含兩個正整數 n, m ,分別表示初始鴿籠數與操作個數。 第二行包含 n 個正整數,第

JZOJ-senior-5932. NOIP2018模擬10.27情報中心

Time Limits: 1500 ms Memory Limits: 262144 KB Description 飛紛火戰來年近國 D 和國 C 飛亂子鴿來年近國 D 和國 C 最近,C 國成功地滲透進入了 D 國的一個城市。這個城市可以抽象成一張有 n 個節點,節點之間有

JZOJ-senior-5931. NOIP2018模擬10.27氣泡排序

Time Limits: 1000 ms Memory Limits: 262144 KB Description 氣泡排序的交換次數被定義為交換過程的執行次數。 小 S 開始專注於研究⻓度為 n 的排列,他想知道,在你運氣足夠好的情況下(即每次氣泡排序的交換次數都是可能的

NOIP2018模擬10.26總結

T1 這個題考試的時候仔細想想應該可以切掉的。。。 先轉換成計數問題,最後求一下逆元,除以區間個數就ok。 對於20%20\%20%的資料,可以按照題意模擬。 對於40%40\%40%的資料,觀察到線段樹上每個節點的貢獻獨立,列舉所有節點,一個節點的貢獻是可以

jzoj5938. NOIP2018模擬10.30分離計劃(二分)

5938. 【NOIP2018模擬10.30】分離計劃 Description 眾所周知,小Z擁有者足以毀滅世界的力量,可惜他不能控制這份力量,小J和小Z的關係十分親密,一天小J預感到了小Z體內的力量將要爆發。 這次爆發的力量比以往都要強大,以至於將小Z分為了兩個整體,彼此之間靠著萬

jzoj5935. NOIP2018模擬10.29小凱學數學(區間dp)

5935. 【NOIP2018模擬10.29】小凱學數學 Description 由於小凱上次在找零問題上的疑惑,給大家在考場上帶來了很大的麻煩,他決心好好學習數學 本次他挑選了位運算專題進行研究 他發明了一種叫做“小凱運算”的運算子: a$b =( (a&b) + (a|b

jzo5934. NOIP2018模擬10.29列隊(二分圖匹配)

5934. 【NOIP2018模擬10.29】列隊 Description Sylvia是一個熱愛學習的女孩子。 在平時的練習中,他總是能考到std以上的成績,前段時間,他參加了一場練習賽,眾所周知,機房是一個 的方陣。這天,他又打爆了std,感到十分無聊,便想要hack機房內同學的

jzoj5922. NOIP2018模擬10.23sequence(組合數)

5922. 【NOIP2018模擬10.23】sequence Description 小 F 是一位 Hack 國的居民,他生活在一條長度為 n 的街道上,這個街道上總共有 n 個商店。每個商店裡售賣著不同的 Hack 技能包,每個商店本身也會有個便利值。初始時,每個商店的便利值均

jzoj5920. NOIP2018模擬10.21風箏(dp,最長上升子序列)

5920. 【NOIP2018模擬10.21】風箏 Description 當一陣風吹來,風箏飛上天空,為了你,而祈禱,而祝福,而感動…… Description oyiya 在 AK 了 IOI 之後來到了鄉下,在田野中玩耍,放鬆身心。 他發現前面有一排小朋

jzoj5919. NOIP2018模擬10.22逛公園(tarjan,二分)

5919. 【NOIP2018模擬10.22】逛公園 Description 琥珀色黃昏像糖在很美的遠方,思念跟影子在傍晚一起被拉長…… Description 小 B 帶著 GF 去逛公園,公園一共有 n 個景點,標號為 1 . . . n。景點之間有 m

JZOJ 5937. NOIP2018模擬10.30斬殺計劃

問題 小G有n個小弟,第i個小弟有ai點攻擊力,小G有m點血量。 小J在小G找小第的時間裡去找小Z學到了膜法,他在大戰前配置了三種魔法藥水 1:複用型藥水:花費1法力值,選擇小G的攻擊力小於等於2的一個小弟讓他跟隨自己(變為自己的小弟並且攻擊力和屬於小G時一樣

JZOJ 5936. NOIP2018模擬10.29逛公園

題目 解題思路 50分可以直接暴力。 能用一個變數儲存的,絕對不允許用陣列!! 定址時間卡爆!!! # d

JZOJ 5925. NOIP2018模擬10.25naive 的瓶子

題目 有 n 個瓶子,它們在桌子上排成一排。第 i 個瓶子的顏色為 ci,每次操作可以選擇兩個相鄰的瓶子,消耗他們顏色的數值乘積的代價將其中一個瓶子的顏色變成另一個瓶子的顏色。 現在要讓所以瓶子的顏色都一樣,操作次數不限,但要使得操作的總代價最小。 題解 比賽時看錯題了,看成