LSNU寒假集訓 題解

目錄

LSNU寒假第一場(基礎算法+幾何)

A - Fifa and Fafa

B - Anton and Lines

C - Minimum path

D - Thematic Contests

E - Balanced Playlist

F - Median String

G - String Reconstruction

H - Palindrome Pairs

 

LSNU寒假第二場(動態規劃)

A - Vitamins

B - Polycarp and Div 3

 

LSNU寒假第三場(數據結構)

A - A and B and Compilation Errors

B - Maximum Absurdity

C - Contest Balloons

D - Dense Subsequence

E - Kostya the Sculptor

 

LSNU寒假第四場(圖論+搜索)

A - Cyclic Components

B - Fight Against Traffic

C - Love Rescue

 

LSNU寒假第五場(數論)

A - The Wall (medium)

B - Selection of Personnel

C - New Year and the Sphere Transmission

D - Social Circles

E - Enlarge GCD

G - Remainders Game


 

LSNU寒假第一場(基礎算法+幾何)

比賽傳送門

A - Fifa and Fafa

Fifa and Fafa are sharing a flat. Fifa loves video games and wants to download a new soccer game. Unfortunately, Fafa heavily uses the internet which consumes the quota. Fifa can access the internet through his Wi-Fi access point. This access point can be accessed within a range of r meters (this range can be chosen by Fifa) from its position. Fifa must put the access point inside the flat which has a circular shape of radius R. Fifa wants to minimize the area that is not covered by the access point inside the flat without letting Fafa or anyone outside the flat to get access to the internet.

The world is represented as an infinite 2D plane. The flat is centered at (x1, y1) and has radius R and Fafa's laptop is located at (x2, y2), not necessarily inside the flat. Find the position and the radius chosen by Fifa for his access point which minimizes the uncovered area.

Input

The single line of the input contains 5 space-separated integers R, x1, y1, x2, y2 (1 ≤ R ≤ 105, |x1|, |y1|, |x2|, |y2| ≤ 105).

Output

Print three space-separated numbers xap, yap, r where (xap, yap) is the position which Fifa chose for the access point and r is the radius of its range.

Your answer will be considered correct if the radius does not differ from optimal more than 10 - 6 absolutely or relatively, and also the radius you printed can be changed by no more than 10 - 6 (absolutely or relatively) in such a way that all points outside the flat and Fafa's laptop position are outside circle of the access point range.

Examples

Input

5 3 3 1 1

Output

3.7677669529663684 3.7677669529663684 3.914213562373095

Input

10 5 5 5 15

Output

5.0 5.0 10.0

題意:

    Fifa和Fafa共用一間公寓。Fifa喜歡電子遊戲,想下載一款新的足球遊戲。不幸的是,Fafa大量使用互聯網,消耗了所有配額。Fifa可以通過他的WiFi接入點上網。這個接入點使附近 r 米範圍內可連上網絡(這個範圍 r 的大小可以由Fifa選擇)。Fifa必須將接入點設置在半徑爲 R 的圓形公寓內。Fifa希望在不讓Fafa或公寓外的任何人接入互聯網的情況下,將接入點未覆蓋的區域最小化。
    世界被表示爲一個無限的二維平面。公寓以(x1, y1)爲中心,半徑爲R, Fafa的筆記本電腦位於(x2, y2),不一定在公寓內。找到Fifa爲他的接入點所選擇的位置和半徑,使得未覆蓋的區域最小化。

    總結題意就是Fifa要在這個圓形的公寓內放置一個wifi,wifi有擺放位置和可自定義的信號半徑,這個描述wifi範圍的圓要儘可能大以覆蓋公寓中更多區域,卻又不能將Fafa的筆記本包進來(避免Fafa連上),更不能超出公寓範圍(避免公寓外的人連上),輸出最優的wifi的擺放位置和信號半徑,且結果誤差要在1e-6以內.

思路:

    其實影響wifi擺放位置與信號半徑的只有Fafa的筆記本和公寓,問題情況基於筆記本和公寓的關係分兩種:

    1.當筆記本在公寓外時,wifi擺放在公寓正中心,信號半徑和公寓半徑相同自然就是最優.

    2.當筆記本在公寓內且不在公寓圓心時,wifi擺放在筆記本與公寓圓心所成直線上纔可得到最大信號半徑如圖,此時wifi的信號半徑r=(R+dis(公寓圓心,Fafa筆記本))/2 ,至於wifi圓心的擺放位置可以通過相似三角形快速得到.即三角形foo'與fww'相似,故而:

                                                                                 \frac{fw'}{fw}=\frac{fo'}{fo}

    故而wifi擺放位置相對於f點的x軸差值爲fw'=fw*fo'/fo,已知f(x1,y1)與o(x2,y2)帶入方程即可得到wifi擺放位置的x座標

                                                                             \frac{ww'}{fw}=\frac{oo'}{fo}

    故而wifi擺放位置相對於f點的y軸差值爲ww'=fw*oo'/fo,已知f(x1,y1)與o(x2,y2)帶入方程即可得到wifi擺放位置的y座標

    3.當筆記本在公寓圓心時,此時的最大信號半徑確定爲R/2,而圓心位置可以在圖中紅圈上的任意一點

AC代碼:

#include <stdio.h>
#include <math.h>

struct point{
	double x,y;
};
// 求兩點距離
double get_two_point_dis(const point &a,const point &b){
	return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}

const double eps=1e-6; // 精度
// 比較兩浮點數大小,相等返回0,a<b返回1,a>b返回-1
int float_compare(const double &a,const double &b){
	if(fabs(a-b)<eps) return 0;
	else if(a<b) return 1;
	else return -1;
}

void solve(){
	double r;
	point flat,fafa_laptop;
	scanf("%lf%lf%lf%lf%lf",&r,&flat.x,&flat.y,&fafa_laptop.x,&fafa_laptop.y);
	double dis=get_two_point_dis(flat,fafa_laptop);
    // 若Fafa筆記本在公寓外
	if(float_compare(r,dis)!=-1){
		printf("%f\n%f\n%f\n",flat.x,flat.y,r);
		return;
	}
    // 若Fafa筆記本在公寓圓心
	if(float_compare(0,dis)==0){
		printf("%.15f\n%.15f\n%.15f\n",flat.x,flat.y+r/2,r/2);
		return;
	}
    // 若Fafa筆記本在公寓內且不在圓心
	double fifa_wifi_r=(dis+r)/2;
	point fifa_wifi;
	fifa_wifi.x=fafa_laptop.x+fifa_wifi_r*(flat.x-fafa_laptop.x)/dis;
	fifa_wifi.y=fafa_laptop.y+fifa_wifi_r*(flat.y-fafa_laptop.y)/dis;
	printf("%.15f\n%.15f\n%.15f\n",fifa_wifi.x,fifa_wifi.y,fifa_wifi_r);
}

int main(){
	solve();
	return 0;
}

B - Anton and Lines

The teacher gave Anton a large geometry homework, but he didn't do it (as usual) as he participated in a regular round on Codeforces. In the task he was given a set of n lines defined by the equations y=k_{i}*x+b_{i}. It was necessary to determine whether there is at least one point of intersection of two of these lines, that lays strictly inside the strip between x_{1}<x_{2}. In other words, is it true that there are 1 ≤ i < j ≤ n and x', y', such that:

  • y{}'=k_{i}*x{}'+b_{i}, that is, point (x', y') belongs to the line number i;
  • y{}'=k_{j}*x{}'+b_{j}, that is, point (x', y') belongs to the line number j;
  • x_{1}<x{}'<x_{2}, that is, point (x', y') lies inside the strip bounded by x_{1}<x_{2}.

You can't leave Anton in trouble, can you? Write a program that solves the given task.

Input

The first line of the input contains an integer n (2 ≤ n ≤ 100 000) — the number of lines in the task given to Anton. The second line contains integers x_{1} and x_{2} ( - 1 000 000 ≤ x_{1} < x_{2} ≤ 1 000 000) defining the strip inside which you need to find a point of intersection of at least two lines.

The following n lines contain integers k_{i}, b_{i} ( - 1 000 000 ≤ k_{i}, b_{i} ≤ 1 000 000) — the descriptions of the lines. It is guaranteed that all lines are pairwise distinct, that is, for any two i ≠ j it is true that either k_{i}\neq k_{j} , or b_{i}\neq b_{j}.

Output

Print "Yes" (without quotes), if there is at least one intersection of two distinct lines, located strictly inside the strip. Otherwise print "No" (without quotes).

Examples

Input

4
1 2
1 2
1 0
0 1
0 2

Output

NO

Input

2
1 3
1 0
-1 3

Output

YES

Input

2
1 3
1 0
0 2

Output

YES

Input

2
1 3
1 0
0 3

Output

NO

Note

In the first sample there are intersections located on the border of the strip, but there are no intersections located strictly inside it.

題意:

    老師給安東佈置了大量的幾何作業,但他沒有(像往常一樣)去做,因爲他參加了一個常規的Codeforces測試。在這個任務中,他得到了由方程 y=k_{i}*x+b_{i} 定義的n條直線。必須確定這兩條直線之間是否存在至少一個交點 (x',y'),該交點嚴格位於x_{1}<x_{2}之間的帶狀區域內。也就是說,是否存在1 ≤ i < j ≤ n, x', y',使得:

  • y{}'=k_{i}*x{}'+b_{i}, 即點(x', y')屬於第i條直線;
  • y{}'=k_{j}*x{}'+b_{j}, 即點(x', y')屬於第j條直線;
  • x_{1}<x{}'<x_{2}, 即點(x', y')位於以x_{1}<x_{2}爲界的帶狀區域內。

    你不能丟下安東不管,對吧?編寫一個程序來解決給定的任務。

    總結題意就是給你n(1e5以內)條直線(輸入保證沒有相同直線),以及x_{1},x_{2},問這n條線段是否存在任意兩條直線的交點正好在(x_{1},x_{2})以內,注意是開區間因爲題目要求嚴格在此區間內.

思路:

      首先因爲數據量級達到1e5導致暴力枚舉所有直線交點判斷是否在(x_{1},x_{2})以內會TLE,故而我們轉變思路研究相交的情況有什麼特別之處.如圖直線L1與直線L2相交於x=x1與x=x2之間的點O

    此時可以發現相交的L1與L2關於x=x1,x=x2的交點在y方向上是順序相反的,而反之不存在交點或者交點在外面時,關於x=x1,x=x2的交點在y方向上順序必然相同.故而可以通過這一點判斷兩直線是否存在(x_{1},x_{2})以內的交點.

    其次若如圖L1L2相交的情況下,L1交x=x1於B,L2交x=x1於A,若存在直線L3與x=x1交於A B之間的點C,我們可知此時L3必與L1或L2相交,因此若存在任意兩相交直線,則必然存在兩相交直線與x=x1的交點在所有n個交點中滿足相鄰

    通過以上兩個加粗的關鍵點我們可以開始編寫算法,先預處理出n條直線與x=x1與x=x2的交點並根據與x=x1的交點y值排序(y值相同時根據與x=x2的交點y值排序),升序降序無所謂

    根據排序得到的n條直線的順序依次比較相鄰的2條直線與x=x1和x=x2的交點y值,判斷是否滿足相反,滿足相反的那一對相鄰直線必相交

AC代碼:

#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const ll inf=1e14;
// 直線結構體 y=kx+b 
struct line{
	ll k,b;
}li[maxn];
// 某條直線與x=x1相交於first,與x=x2相交於second
pair<ll,ll> inters[maxn]; 

int sign(ll t){
	if(t>0) return 1;
	else if(t<0) return -1;
	return 0; 
} 

void solve(){
	int n;
	scanf("%d",&n);
	int x1,x2;
	scanf("%d%d",&x1,&x2);
	for(int i=0;i<n;i++) scanf("%lld%lld",&li[i].k,&li[i].b);
	// 計算與x=x1和x=x2交點y值
	for(int i=0;i<n;i++){
		inters[i].first=li[i].k*x1+li[i].b;
		inters[i].second=li[i].k*x2+li[i].b;
	}
	// 基於與x=x1的交點y值將交點排升序 
	sort(inters,inters+n);
	
	bool flag=false;
	// 檢查n-1組相鄰的兩直線 
	for(int i=1;i<n;i++){
        // 差值的正負體現的是交點在y方向的順序,相乘爲負自然就相反了,此時必相交
		// 特別的交點在x=x1或x=x2上時乘積爲0也不滿足小於0
		if(sign(inters[i-1].first-inters[i].first)*sign(inters[i-1].second-inters[i].second)<0){
			flag=true;
			break;
		}
	}
	if(flag) printf("YES\n");
	else printf("NO\n");
}

int main(){
	solve();
	return 0;
}

C - Minimum path

    You are given a matrix of size n×n filled with lowercase English letters. You can change no more than k letters in this matrix.

    Consider all paths from the upper left corner to the lower right corner that move from a cell to its neighboring cell to the right or down. Each path is associated with the string that is formed by all the letters in the cells the path visits. Thus, the length of each string is 2n−1.

    Find the lexicographically smallest string that can be associated with a path after changing letters in at most k cells of the matrix.

    A string a is lexicographically smaller than a string b, if the first different letter in a and b is smaller in a .

Input

    The first line contains two integers n and k (1≤n≤2000, 0≤k≤n2 ) — the size of the matrix and the number of letters you can change.

    Each of the next n lines contains a string of n lowercase English letters denoting one row of the matrix.

Output

    Output the lexicographically smallest string that can be associated with some valid path after changing no more than k letters in the matrix.

Examples

Input

4 2
abcd
bcde
bcad
bcde

Output

aaabcde

Input

5 3
bwwwz
hrhdh
sepsp
sqfaf
ajbvw

Output

aaaepfafw

Input

7 6
ypnxnnp
pnxonpm
nxanpou
xnnpmud
nhtdudu
npmuduh
pmutsnz

Output

aaaaaaadudsnz

Note

    In the first sample test case it is possible to change letters 'b' in cells (2,1) and (3,1) to 'a', then the minimum path contains cells (1,1),(2,1),(3,1),(4,1),(4,2),(4,3),(4,4). The first coordinate corresponds to the row and the second coordinate corresponds to the column.

 

題意:

    你有一個大小爲n×n的方陣,裏面全是小寫的英文字母。你最多隻能改變這個方陣中的 k 個字母。
    考慮從左上角到右下角的所有路徑,這些路徑從一個單元格移動到相鄰的單元格,只能移動到右邊或下邊相鄰單元格。每個路徑用依次經過的單元格中的字母組成的字符串表示。因此,每個路徑字符串的長度是2n - 1.
    尋找改變最多k個單元格中的字符後能得到的字典序最小的路徑字符串,
    一個字符串a的字典序比字符串b的字典序小,當且僅當ab中第一個不相同的字符是a中更小時.

    總結題意就是給你一個n*n的字母方陣,你能改變這個方陣中最多k個字母,然後以左上角爲起點,右下角爲終點,且只能向右或者向下走,問你所有路徑中字典序最小的是哪條路徑.

思路:

    首先如果僅僅是給我們一個字母方陣,只能向右下走,要找左上角到右下角的最小字典序路徑是很簡單的,因爲只能向右下走這一條件很關鍵,這決定了(0,0)到(n-1,n-1)路徑長度必爲2*n-1,而其第i步一定在第i條對角線上,且由於是最小字典序,我們的情況求解是貪心的.

    故而我們只需要對這2*n-1條對角線從左上到右下依次找對角線上的相連的最小字符即可,而這體現的也正是bfs的核心思想,從近到遠依次遍歷所有狀態,故而這裏可以通過寫循環掃描對角線實現也可以通過bfs實現.

 

    然而問題沒那麼簡單,加了條件可以改變方陣中k個字母之後我們無法直接貪心了,因爲比如baaaa字典序大於azzzz可是如果允許改變一個字符我們把b改成a則aaaaa毫無疑問的大於azzzz的任何改法,故而我們要設法統計k次修改能造成的變動

    畢竟是字典序,誰的前綴a多誰小,故而我們實際上是要使用k次修改修改出前綴a個數儘可能多的路徑字符串,其實就是一種dp最優解,問題初始狀態可描述爲:在(0,0)點前綴全a剩餘k個改變權,故設計dp[i][j]含義如下:

  • dp[i][j]大於等於0時表示從(0,0)到(i,j)的所有路徑字符串中開掛使得全部變爲'a'之後最大的剩餘改變權個數
  • dp[i][j]小於0時表示從(0,0)到(i,j)的所有路徑字符串中開掛後前綴a最多的那個字符串除去前綴a之後的長度*-1

而轉移方程:    dp[i][j]=max(dp[i-1][j]-(dp[i-1][j]<0||lm[i-1][j]!='a'),dp[i][j-1]-(dp[i][j-1]<0||lm[i][j-1]!='a')) (0<=i,j<n)

    就這樣一直轉移到dp[n-1][n-1]爲止,最後dp值爲-1的自然就是前綴a緊接着的位置,取離終點距離最近的-1即可.因爲距離終點最近說明前綴a最多,自然是用完k個改變權之後字典序最小的,這樣k個改變權的影響就不復存在了,對距離終點最近的-1按照之前的對角線掃描或者bfs做就好.

AC代碼:

1.dp加對角線掃描

#include <stdio.h>

const int maxn=2e3+5;
int dir[2][2]={0,1,1,0},dirnum=2; //方向數組,右下

int n,k;
char letter_matrix[maxn][maxn];

int dp[maxn][maxn];
char minimum_path[2*maxn];

void solve(){
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf(" %c",&letter_matrix[i][j]);

	// dp[i][j]大於等於0時表示從(0,0)到(i,j)的所有路徑字符串中開掛使得全部變爲'a'之後最大的剩餘改變權個數
	// dp[i][j]小於0時表示從(0,0)到(i,j)的所有路徑字符串中開掛後前綴a最多的那個字符串除去前綴a之後的長度*-1
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) dp[i][j]=-3*n; //-3*n表示極小值
	dp[0][0]=k;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			// 有改變權時遇到不爲a的則消耗一個改變權將之變爲a,改變權用完之後直接減以達到路徑長度記錄的目的.
			if(dp[i][j]<0||letter_matrix[i][j]!='a') dp[i][j]--;
			for(int k=0;k<dirnum;k++){
				int ti=i+dir[k][0],tj=j+dir[k][1];
				if(ti<n&&tj<n&&dp[ti][tj]<dp[i][j]) dp[ti][tj]=dp[i][j];
			}
		}
	}
	if(dp[n-1][n-1]<0) for(int i=0;i<2*n-1+dp[n-1][n-1];i++) minimum_path[i]='a';
	else for(int i=0;i<2*n-1;i++) minimum_path[i]='a';

	// 對角線遍歷過程中dp值爲-1象徵着這個點是當前所有最小字典序路徑字符串中合法的末尾之一
	for(int i=2*n-1+dp[n-1][n-1];i<2*n-1;i++){ //遍歷對角線
		// 遍歷這條對角線上的所有點,取dp值爲-1的所有點中的最小字符
		char min_char='z'+1;
		for(int x=0;x<n;x++){
			int y=i-x;
			if(0<=y&&y<n&&dp[x][y]==-1&&letter_matrix[x][y]<min_char) min_char=letter_matrix[x][y]; 
		}
		// 將這條對角線上爲最小字符的點的右點與下點dp值置爲-1
		for(int x=0;x<n;x++){
			int y=i-x;
			if(0<=y&&y<n&&dp[x][y]==-1&&letter_matrix[x][y]==min_char){
				for(int j=0;j<dirnum;j++){
					int tx=x+dir[j][0],ty=y+dir[j][1];
					if(tx<n&&ty<n) dp[tx][ty]=-1;
				}
			}
		}
		minimum_path[i]=min_char;
	}
	minimum_path[2*n-1]='\0';
	printf("%s\n",minimum_path);
}


int main(){
	solve();
	return 0;
}

2.dp加bfs

#include <stdio.h>
#include <queue>
#include <memory.h>
#include <algorithm>
using namespace std;
typedef pair<int,int> pa;
const int maxn=2e3+5;
int dir[2][2]={0,1,1,0},dirnum=2; //方向數組,右下

int n,k;
char letter_matrix[maxn][maxn];

bool flag[maxn][maxn];
int dp[maxn][maxn];
char minimum_path[2*maxn];

void solve(){
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf(" %c",&letter_matrix[i][j]);

	// dp[i][j]大於等於0時表示從(0,0)到(i,j)的所有路徑字符串中開掛使得全部變爲'a'之後最大的剩餘改變權個數
	// dp[i][j]小於0時表示從(0,0)到(i,j)的所有路徑字符串中開掛後前綴a最多的那個字符串除去前綴a之後的長度*-1
	for(int i=0;i<n;i++) for(int j=0;j<n;j++) dp[i][j]=-3*n; //-3*n表示極小值
	dp[0][0]=k;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			// 有改變權時遇到不爲a的則消耗一個改變權將之變爲a,改變權用完之後直接減以達到路徑長度記錄的目的.
			if(dp[i][j]<0||letter_matrix[i][j]!='a') dp[i][j]--;
			for(int k=0;k<dirnum;k++){
				int ti=i+dir[k][0],tj=j+dir[k][1];
				if(ti<n&&tj<n) dp[ti][tj]=max(dp[ti][tj],dp[i][j]);
			}
		}
	}
	if(dp[n-1][n-1]>=0){ //若開掛後能直接到終點
		for(int i=0;i<2*n-1;i++) minimum_path[i]='a';
	}else{ //若開掛後不能直接到終點
		int idx=2*n-1+dp[n-1][n-1];  
		for(int i=0;i<idx;i++) minimum_path[i]='a';  // 部分開掛
		for(int i=idx;i<2*n-1;i++) minimum_path[i]='z'+1; // 初始化極大值

		memset(flag,true,sizeof(flag)); //避免重複壓入隊列,flag[i][j]=false說明(i,j)點已被壓入隊列
		queue<pa> que;
		for(int x=0;x<n;x++){ //遍歷斜線上dp值爲-1的點,即所有最優起點
			int y=idx-x; //x+y=idx
			if(0<=y&&y<n&&dp[x][y]==-1){
				if(minimum_path[x+y]>=letter_matrix[x][y]){
					minimum_path[x+y]=letter_matrix[x][y];
					flag[x][y]=false;
					que.push(make_pair(x,y));
				}
			}
		}
		while(!que.empty()){
			pa t=que.front();
			que.pop();
			flag[t.first][t.second]=true;
			// 若此位置字符串並非路徑字符串中記錄的同步數最優解時跳過
			if(minimum_path[t.first+t.second]!=letter_matrix[t.first][t.second]) continue; 
			for(int i=0;i<dirnum;i++){
				int tx=t.first+dir[i][0],ty=t.second+dir[i][1];
				if(tx<n&&ty<n&&minimum_path[tx+ty]>=letter_matrix[tx][ty]&&flag[tx][ty]){
					minimum_path[tx+ty]=letter_matrix[tx][ty];
					flag[tx][ty]=false;
					que.push(make_pair(tx,ty)); 
				}
			}
		}
	}
	minimum_path[2*n-1]='\0';
	printf("%s\n",minimum_path);
}


int main(){
	solve();
	return 0;
}

D - Thematic Contests

    Polycarp has prepared n competitive programming problems. The topic of the i-th problem is a_{i} , and some problems' topics may coincide.

    Polycarp has to host several thematic contests. All problems in each contest should have the same topic, and all contests should have pairwise distinct topics. He may not use all the problems. It is possible that there are no contests for some topics.

    Polycarp wants to host competitions on consecutive days, one contest per day. Polycarp wants to host a set of contests in such a way that:

  • number of problems in each contest is exactly twice as much as in the previous contest (one day ago), the first contest can contain arbitrary number of problems;
  • the total number of problems in all the contests should be maximized.

    Your task is to calculate the maximum number of problems in the set of thematic contests. Note, that you should not maximize the number of contests.

Input

    The first line of the input contains one integer n (1<=n<=10^{5} ) — the number of problems Polycarp has prepared.

    The second line of the input contains n integers a_{1},a_{2}....a_{n}(1<=a_{i}<=10^{9}) where ai is the topic of the i-th problem.

Output

    Print one integer — the maximum number of problems in the set of thematic contests.

Examples

Input

18
2 1 2 10 2 10 10 2 2 1 10 10 10 10 1 1 10 10

Output

14

Input

10
6 6 6 3 6 1000000000 3 3 6 6

Output

9

Input

3
1337 1337 1337

Output

3

Note

In the first example the optimal sequence of contests is: 2 problems of the topic 1, 4 problems of the topic 2, 8 problems of the topic 10.

In the second example the optimal sequence of contests is: 3 problems of the topic 3, 6 problems of the topic 6.

In the third example you can take all the problems with the topic 1337 (the number of such problems is 3 so the answer is 3) and host a single contest.

 

題意:

    Polycarp準備了n個用於比賽的編程問題。第i個問題的主題是a_{i},有些問題的主題可能是一致的。

    Polycarp將要舉辦一些主題競賽。每一場比賽的所有問題都應該有相同的主題,所有的比賽都應該有兩兩不同的主題。他可能不會利用所有的問題。有些主題可能沒有競賽。

    Polycarp希望連續舉辦比賽,每天一場。Polycarp希望以這樣的方式舉辦一系列比賽:

  • 每場比賽的問題數正好是前一場比賽(一天前)的兩倍,第一場比賽可以包含任意數量的問題;
  • 所有競賽的問題總數應該最大化

    你的任務是計算一組主題競賽中問題的最大數量。注意,您不應該最大化競賽的數量。

    總結題意就是Polycarp有n個問題,每個問題有類型(可能重複),(topic就好像動態規劃類型,搜索類型,數論類型,計算幾何類型...),現在基於這些問題一天一場舉辦任意多場主題不重複的比賽,每場比賽問題數目是上場的2倍,且每場比賽主題不重複,問你所有競賽的問題總數最大的舉辦方式能包含多少道問題.

思路:

    由於問題總數n是在2e5以內,故而我們可知任意一種主題問題的總數不會超過n,題目無非是要找一個比爲2的等比數列,由於單種問題數目在2e5以內故而我們可以估計這個等比數列的項數不超過18個.

    知道了這些信息之後我們可以考慮枚舉這個等比數列的起點,然後檢查其每一項是否存在某個對應種類問題即可,而檢查可以通過預處理所有種類問題數目並排序後使用二分查找

    最後進行複雜度分析,空間上只需要一個map用於問題分類統計,一個n大小數組用於各種類問題數目記錄.而時間複雜度上,由於單種問題數目在2e5以內,故而起點枚舉複雜度最高2e5,而項數最多18個,每一項的檢查通過二分效率在logm(m是問題種數),總複雜度n*18*logm左右,看似容易爆,然而枚舉起點的n是指所有種類問題中數目最大的問題數目,並非完全的2e5的n,除非全部問題都是同一種類.而logm的m也非2e5而是問題種數,除非全部問題都是不同種類,故而n與logm總有一個會偏小,總體效率可行.

AC思路:

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
const int maxn=2e5+5;

map<int,int> problems;
map<int,int>::iterator ite;
int topic[maxn],topic_num=0;
void solve(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		int t;
		cin>>t;
		problems[t]++;
	}
	for(ite=problems.begin();ite!=problems.end();ite++) topic[topic_num++]=ite->second;
	sort(topic,topic+topic_num);
	int ans=-1;
	for(int i=1;i<=topic[topic_num-1];i++){// 枚舉等比數列首項
		int sum=0;
		int now=i,idx=0;//[idx,topic_num]爲當前查找now的合法區域,因爲問題不能重複使用
		while(1){
			idx=lower_bound(topic+idx,topic+topic_num,now)-topic;
			if(idx==topic_num) break;
			idx++;
			sum+=now;
			now<<=1;
		}
		if(sum>ans) ans=sum;
	}
	cout<<ans<<endl;
}



int main(){
	solve();
	return 0;
}

E - Balanced Playlist

    Your favorite music streaming platform has formed a perfectly balanced playlist exclusively for you. The playlist consists of n tracks numbered from 1 to n. The playlist is automatic and cyclic: whenever track i finishes playing, track i+1 starts playing automatically; after track n goes track 1.

    For each track i, you have estimated its coolness a_{i}. The higher a_{i} is, the cooler track i is.

    Every morning, you choose a track. The playlist then starts playing from this track in its usual cyclic fashion. At any moment, you remember the maximum coolness x of already played tracks. Once you hear that a track with coolness strictly less than \frac{x}{2} (no rounding) starts playing, you turn off the music immediately to keep yourself in a good mood.

    For each track i , find out how many tracks you will listen to before turning off the music if you start your morning with track i , or determine that you will never turn the music off. Note that if you listen to the same track several times, every time must be counted.

Input

    The first line contains a single integer n (2<=n<=10^{5}), denoting the number of tracks in the playlist.

    The second line contains n integers a_{1},a_{2}....a_{n} (1<=a_{i}<=10^{9}), denoting coolnesses of the tracks.

Output

    Output n integers c_{1},c_{2},...c_{n} where c_{i} is either the number of tracks you will listen to if you start listening from track i or −1 if you will be listening to music indefinitely.

Examples

Input

4
11 5 2 7

Output

1 1 3 2

Input

4
3 2 5 3

Output

5 4 3 6

Input

3
4 3 6

Output

-1 -1 -1

Note

In the first example, here is what will happen if you start with...

  • track 1: listen to track 1, stop as a_{2}<\frac{a_{1}}{2}.
  • track 2: listen to track 2, stop as a_{3}<\frac{a_{2}}{2}.
  • track 3: listen to track 3, listen to track 4, listen to track 1, stop as a_{2}<\frac{max(a_{3},a_{4},a_{1})}{2}.
  • track 4: listen to track 4, listen to track 1, stop as a_{2}<\frac{max(a_{4},a_{1})}{2}.

In the second example, if you start with track 4, you will listen to track 4, listen to track 1, listen to track 2, listen to track 3, listen to track 4 again, listen to track 1 again, and stop as a_{2}<\frac{max(a_{4},a_{1},a_{2},a_{3},a_{4},a_{1})}{2} Note that both track 1 and track 4 are counted twice towards the result.

 

題意:

    你最喜歡的音樂流媒體平臺爲你量身打造了一個完美平衡的播放列表。播放列表包含從1到n編號的n首歌曲,播放列表是自動循環的:每當歌曲 i 結束播放時,歌曲 i+1 開始自動播放;在歌曲 n 之後是歌曲1.

    對於每個歌曲 i ,你爲他定義了一個 coolness(酷?) 值a_{i}a_{i} 值越高,歌曲 i 越酷。

    每天早上,你選擇一首歌曲。播放列表從這首歌開始,以它通常的循環方式播放。在任何時候,你都記得已經播放過的歌曲的最大 coolness 值,當你聽到某首coolness值嚴格小於\frac{x}{2}(不要四捨五入)的歌曲開始播放時,爲了讓自己保持一個好心情,你立即關掉音樂播放器.
    對於每個歌曲 i ,如果你早上第一首聽的是歌曲 i ,找出在你關掉音樂之前會聽多少首歌曲,或者決定你永遠都不會關掉歌曲。注意,如果你聽到同一首歌曲多次,每次都要被數進來。

    總結題意就是會給你n首歌曲的coolness值,讓你輸出n個數值ans,ans[i]表示從第i首歌開始聽,直到聽到某首歌曲coolness值小於之前聽過的所有歌曲的最大coolness值的一半時就關閉音樂,這期間總共聽過多少首就輸出多少,如果一直停不下來就輸出-1;

思路:

    首先保存這n首歌的最大coolness和最小coolness值,當最小的coolness值都大於等於最大的coolness值的一半時自然歌就無限循環了,此時輸出n個-1;

    否則我們枚舉所有n個位置,使用一個mutiset保存所有經過的點,直到枚舉到值小於mutiset中最大值一半的點爲止,則此時mutiset的大小就是路徑長度,刪除掉這個點繼續下一次枚舉.

    暴力枚舉顯然極易tle,我們這裏使用一個技巧,假設第i首歌爲開始時是在播放第x首歌時停止的,那我們計算第i+1首歌之前自然是要在mutiset中移除第i首歌的coolness值a[i],然而第i+1首歌的停止位置可以接着從x開始判斷,原因如下:

    因爲移除第i首歌的coolness值a[i]之後,其後路徑中不是以a[i]作爲最大值判斷合格的點自然依舊合格,是以a[i]判斷合格的點比如a[t],說明i到t之間的值都小於等於a[i],而a[t]既然大於a[i]等於/2,自然也大於等於比a[i]小的值/2,故而a[t]必然依舊合格.

AC代碼:

#include <iostream>
#include <set>
using namespace std;
const int maxn=1e5+5;
const int inf=1e9+5;
int n;
int a[maxn];
int ans[maxn];
multiset<int> s;
multiset<int>::iterator ite;
void solve(){
	cin>>n;
	int tmin=inf,tmax=0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		tmin=min(a[i],tmin);
		tmax=max(a[i],tmax);
	}
	if(tmax/2.0<=tmin){
		printf("-1");
		for(int i=1;i<n;i++) printf(" -1");
		printf("\n");
		return;
	}
	int now=0;
	for(int i=0;i<n;i++){
		// 以循環隊列思路向後枚舉
		while(s.empty()||a[now]>=*(--s.end())/2.0){
			s.insert(a[now]);
			now=(now+1)%n;
		}
		ans[i]=s.size();
		s.erase(s.find(a[i]));
	}
	printf("%d",ans[0]);
	for(int i=1;i<n;i++) printf(" %d",ans[i]);
	printf("\n");
}



int main(){
	ios::sync_with_stdio(false);
    cin.tie(0);
	solve();
	return 0;
}

F - Median String

    You are given two strings s and t, both consisting of exactly k lowercase Latin letters, s is lexicographically less than t.

    Let's consider list of all strings consisting of exactly k lowercase Latin letters, lexicographically not less than s and not greater than t (including s and t) in lexicographical order. For example, for k=2, s="az" and t="bf" the list will be ["az", "ba", "bb", "bc", "bd", "be", "bf"].

    Your task is to print the median (the middle element) of this list. For the example above this will be "bc".

    It is guaranteed that there is an odd number of strings lexicographically not less than s and not greater than t.

Input

    The first line of the input contains one integer k (1<=k<=2*10^{5}) — the length of strings.

    The second line of the input contains one string s consisting of exactly k lowercase Latin letters.

    The third line of the input contains one string t consisting of exactly k lowercase Latin letters.

    It is guaranteed that s is lexicographically less than t .

    It is guaranteed that there is an odd number of strings lexicographically not less than s and not greater than t.

Output

    Print one string consisting exactly of k lowercase Latin letters — the median (the middle element) of list of strings of length k lexicographically not less than s and not greater than t.

Examples

Input

2
az
bf

Output

bc

Input

5
afogk
asdji

Output

alvuw

Input

6
nijfvj
tvqhwp

Output

qoztvz

 

題意:

    你有兩個字符串s和t,都是由k個小寫的拉丁字母組成,s的字典序比t小。
    讓我們按字典序來列出一個列表,包含所有由k個小寫拉丁字母組成字典序不小於s不大於t(包括s和t)的字符串。例如,對於k=2, s="az"和t=“bf”列表將會是(“az”,“ba”,“bb”,“bc”,“bd”,“be”,“bf”)。
    您的任務是打印這個列表的中位數(中間元素)。對於上面的例子,這將是“bc”。
    輸入保證有奇數個字符串的字典序不小於s不大於t。

    總結題意就是已知兩個字符串是s,t,分別長度k,列出一個列表包含長度爲k字典序在s與t之間的所有字符串,輸出中位數字符串.

思路:

    其實這個字符串和我們的數字沒什麼差別,只是我們的數字是10進制,這個字符串是26進制,故而我們把這個字符串看作大數進行處理即可,'a'看成0,'b'看成1...'z'看成25,故而我們中位字符串的求取就模擬數字求中位數,即(a+b)/2即可.

AC代碼:

#include <stdio.h>
#include <math.h>
const int maxk=2e5+5;
char s[maxk],t[maxk],ans[maxk];

int min(char a,char b){
	return a<b?a:b;
}

void solve(){
	int k;
	scanf("%d%s%s",&k,&s,&t);
	int jinwei=0;// 進爲
	for(int i=k-1;i>=0;i--){ //模擬加法
		ans[i]=(s[i]+t[i]+jinwei-194)%26;
		jinwei=(s[i]+t[i]+jinwei-194)/26;
	}
	for(int i=0;i<k;i++){  //模擬除2
		int temp=jinwei;
		jinwei=(ans[i]+jinwei*26)%2;
		ans[i]=(ans[i]+temp*26)/2;
	}
	for(int i=0;i<k;i++) ans[i]+=97;
	ans[k]='\0';
	printf("%s\n",ans);
}
// abcdefghijklmnopqrstuvwxyz


int main(){
	solve();
	return 0;
}

G - String Reconstruction

    Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun of him and hid the string s. Ivan preferred making a new string to finding the old one.

    Ivan knows some information about the string s. Namely, he remembers, that string t_{i} occurs in string s at least k_{i} times or more, he also remembers exactly k_{i} positions where the string t_{i} occurs in string s: these positions are x_{i,1},x_{i,2}....,x_{i,k_{i}} He remembers n such strings ti.

    You are to reconstruct lexicographically minimal string s such that it fits all the information Ivan remembers. Strings ti and string s consist of small English letters only.

Input

The first line contains single integer n (1<=n<=10^{5}) — the number of strings Ivan remembers.

The next n lines contain information about the strings. The i-th of these lines contains non-empty string t_{i}, then positive integer k_{i}, which equal to the number of times the string t_{i} occurs in string s, and then k_{i} distinct positive integers x_{i,1},x_{i,2}....,x_{i,k_{i}} in increasing order — positions, in which occurrences of the string ti in the string s start. It is guaranteed that the sum of lengths of strings ti doesn't exceed 10^{6}, 1<=x_{i,j}<=10^{6}, 1<=k_{i}<=10^{6}, and the sum of all ki doesn't exceed 10^{6} . The strings t_{i} can coincide.

It is guaranteed that the input data is not self-contradictory, and thus at least one answer always exists.

Output

Print lexicographically minimal string that fits all the information Ivan remembers.

Examples

Input

3
a 4 1 3 5 7
ab 2 1 5
ca 1 4

Output

abacaba

Input

1
a 1 3

Output

aaa

Input

3
ab 1 1
aba 1 3
ab 2 3 5

Output

ababab

題意:

    伊萬有一串由小英文字母組成的字符串。然而,他的朋友茱莉亞卻拿他開玩笑,把字符串藏了起來。相比於去找舊的伊萬寧願做一根新的字符串.
    Ivan知道一些關於字符串s的信息。也就是說,他記得,字符串 t_{i} 在字符串s中出現至少 k_{i} 次或更多,他還記得字符串 t_{i} 在字符串s中 出現的確切位置:這些位置是 x_{i,1},x_{i,2}....,x_{i,k_{i}} 他能記住的由n條這樣的字符串。
    你要按照字典順序重建最小的字符串,使它符合Ivan所記得的所有信息。字符串 t_{i} 和字符串s由很小的英文字母組成

    總結題意就是現在已知n個字符串,以及分別在原串中出現的位置,要求重建出滿足所給限制的字典序最小的字符串.

思路:

    咋一看這道題的數據好些很大很大,然而由於所有字符串t_{i}的和不超過1e6,所有 k_{i} 的和不超過1e6故而這道題依舊可做.

    我們考慮複雜度升高的核心就在重複填寫同一位置字符,雖然整個答案字符串長度不超過2e6,其實某一位置的字符是什麼由記憶中的一個字符串即可確定,故而我們可以預處理一個flag數組預處理記憶中字符串的所有起點,根據flag數組從左向右掃描,每個時刻僅僅確定一個剩餘字符最長的當前字符串,這樣的話每個位置僅僅會由一個字符串確定,效率會加速到O(n);

AC代碼:

#include <iostream>
#include <memory.h>
using namespace std;
const int maxn=1e5+5;
const int maxt=1e6+5;

string s[maxn];
int flag[2*maxt]; // flag[i]=x表示在第i位置開始應該是字符串s[x],爲-1表示不是某個字符串的開始
char ans[2*maxt];

void solve(){
	int n;
	cin>>n;
	memset(flag,-1,sizeof(flag));
	int end=0; // 記錄記憶中字符串末尾
	for(int i=0;i<n;i++){
		int num;
		cin>>s[i]>>num;
		for(int j=0;j<num;j++){
			int temp;
			scanf("%d",&temp);
			temp--;
            // 此位置還不是某字符串的開始 或 當前字符串是比已知更長的字符串 時更新
			if(flag[temp]==-1||s[i].length()>s[flag[temp]].length()){
				flag[temp]=i;
				end=max(end,temp+(int)s[i].length()); 
			}
		}
	}
	ans[end]='\0';
	// nowstr,nowpos表示當前是字符串s[nowstr]的第nowpos個字符
	int nowstr=-1,nowpos=0;
	for(int i=0;i<end;i++){
		if(flag[i]!=-1){
			if(nowstr==-1||s[flag[i]].length()>s[nowstr].length()-nowpos){
				nowstr=flag[i];
				nowpos=0;
			}
		}
		if(nowstr==-1) ans[i]='a'; // 默認a以保障字典序最小
		else{
            // 用一個
			ans[i]=s[nowstr][nowpos++];
            // 若字符串用完了
			if(nowpos>=s[nowstr].length()) nowstr=-1; 
		}
	}
	printf("%s\n",ans);
}

int main(){
	solve();
	return 0;
}

H - Palindrome Pairs

After learning a lot about space exploration, a little girl named Ana wants to change the subject.

Ana is a girl who loves palindromes (string that can be read the same backwards as forward). She has learned how to check for a given string whether it's a palindrome or not, but soon she grew tired of this problem, so she came up with a more interesting one and she needs your help to solve it:

You are given an array of strings which consist of only small letters of the alphabet. Your task is to find how many palindrome pairs are there in the array. A palindrome pair is a pair of strings such that the following condition holds: at least one permutation of the concatenation of the two strings is a palindrome. In other words, if you have two strings, let's say "aab" and "abcac", and you concatenate them into "aababcac", we have to check if there exists a permutation of this new string such that it is a palindrome (in this case there exists the permutation "aabccbaa").

Two pairs are considered different if the strings are located on different indices. The pair of strings with indices (i,j)

is considered the same as the pair (j,i).

Input

The first line contains a positive integer N (1<=N<=10^{5} ), representing the length of the input array.

Eacg of the next N

lines contains a string (consisting of lowercase English letters from 'a' to 'z') — an element of the input array.

The total number of characters in the input array will be less than 10^{6}.

Output

Output one number, representing how many palindrome pairs there are in the array.

Examples

Input

3
aa
bb
cd

Output

1

Input

6
aab
abcac
dffe
ed
aa
aade

Output

6

Note

The first example:

  1. aa +bb →abba.

The second example:

  1. aab +abcac = aababcac →aabccbaa
  2. aab +aa =aabaa
  3. abcac +aa = abcacaa →aacbcaa
  4. dffe +ed = dffeed →fdeedf
  5. dffe +aade = dffeaade →adfaafde
  6. ed +aade = edaade → aeddea

 

題意:

    在學習了很多關於太空探索的知識後,一個名叫安娜的小女孩想要換個科目。
    安娜是一個喜歡迴文的女孩。她已經學會了如何檢查給定的字符串是否爲迴文,但很快她就厭倦了這個問題,所以她想出了一個更有趣的問題,她需要你的幫助來解決它:
    你有一個字符串數組,只由字母表中小寫字母組成。你的任務是找出數組中有多少個迴文對。迴文對是這樣的一對字符串:兩個字符串連接的至少一個排列是迴文。換句話說,如果你有兩個字符串,比如“aab”和“abcac”,你把它們連接到“aababcac”,我們必須檢查這新字符串是否存在一個迴文的排列(在這種情況下,存在“aabccbaa”的排列)。
    如果字符串位於不同的索引上,則認爲兩對是不同的。索引爲(i,j)和(j,i)的字符串對被認爲是相同的一對.

    總結題意就是現在給你n個字符串讓你輸出這些字符串有多少對字符串僅僅由此兩個字符串中的所有字符可以組成一個迴文串.

思路:

    核心在於字符串太多有1e5個,雖然輸入說明所有字符串長度和在1e6以內.所以我們首先考慮什麼情況下兩個字符串中所有字符可能組成迴文串:迴文串的特點就是基於字符串中心對稱,故而隱含一個屬性,小於等於一種字符個數爲奇數個,其餘皆爲偶數個時才行.

    故而對於每個字符串我們可以預處理一個與之對應的特徵值,特徵值有26個位有效,其中第i個二進制位爲1表示'a'+i字符有奇數個,否則有偶數個,這樣的話我們比對兩字符串的特徵值是否只相差最多一個二進制位即可知曉是否可組成迴文串.

    然而即使如此,枚舉所有字符串隊依舊需要n*n,故而我們反向思考,由某個字符串出發主動尋找是否存在和我只有最多一個二進制位相差的數字,而查找存在多少個預處理之後使用二分upper_bound-lower_bound即可以logn複雜度知曉有幾個.

    預處理複雜度1e6,排序複雜度nlogn,查找複雜度n*27*2logn,總複雜度勉強可接受.

AC代碼:

#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
const int maxs=1e6+5;
char s[maxs];
int feature[maxn];
void solve(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%s",s);
		int idx=0;
		// 使用異或疊加每一個字符'?'的影響到第 '?'-'a' 個二進制位 
		while(s[idx]) feature[i]^=1<<(s[idx++]-'a'); 
	}
	sort(feature,feature+n);
	long long ans=0;
	for(int i=0;i<n;i++){
		// 0個二進制位不同時,排除自己那個1 
		ans+=upper_bound(feature,feature+n,feature[i])-lower_bound(feature,feature+n,feature[i])-1;
		// 第j個進制位不同時 
		for(int j=0;j<26;j++){
			int temp=feature[i]^(1<<j);
			ans+=upper_bound(feature,feature+n,temp)-lower_bound(feature,feature+n,temp);
		}
	}
	// 注意除二排除重複情況 
	ans/=2;
	printf("%lld\n",ans);
}

int main(){
	solve();
	return 0;
}

 

LSNU寒假第二場(動態規劃)

比賽傳送門

A - Vitamins

    Berland shop sells n kinds of juices. Each juice has its price c_{i}. Each juice includes some set of vitamins in it. There are three types of vitamins: vitamin "A", vitamin "B" and vitamin "C". Each juice can contain one, two or all three types of vitamins in it.

    Petya knows that he needs all three types of vitamins to stay healthy. What is the minimum total price of juices that Petya has to buy to obtain all three vitamins? Petya obtains some vitamin if he buys at least one juice containing it and drinks it.

Input

    The first line contains a single integer n (1≤n≤1000)— the number of juices.

    Each of the next n lines contains an integer ci (1≤ c_{i} ≤100000) and a string si — the price of the i-th juice and the vitamins it contains. String si contains from 1 to 3 characters, and the only possible characters are "A", "B" and "C". It is guaranteed that each letter appears no more than once in each string si. The order of letters in strings s_{i} is arbitrary.

Output

    Print -1 if there is no way to obtain all three vitamins. Otherwise print the minimum total price of juices that Petya has to buy to obtain all three vitamins.

Examples

Input

4
5 C
6 B
16 BAC
4 A

Output

15

Input

2
10 AB
15 BA

Output

-1

Input

5
10 A
9 BC
11 CA
4 A
5 B

Output

13

Input

6
100 A
355 BCA
150 BC
160 AC
180 B
190 CA

Output

250

Input

2
5 BA
11 CB

Output

16

Note

In the first example Petya buys the first, the second and the fourth juice. He spends 5+6+4=15 and obtains all three vitamins. He can also buy just the third juice and obtain three vitamins, but its cost is 16 , which isn't optimal.

In the second example Petya can't obtain all three vitamins, as no juice contains vitamin "C".

 

題意:

    伯蘭商店出售n種果汁。每種果汁都有自己的價格區間.每種果汁都含有一些維生素。維生素有三種:維生素A、維生素B和維生素C。每種果汁都含有一種、兩種或三種維生素。

    彼佳知道他需要這三種維生素來保持健康。Petya購買三種維生素所需的果汁的最低總價是多少?如果Petya買了至少一種含維生素的果汁並飲用,他就能獲得一些維生素。

    總結題意就是現在有n種果汁可以買,分別有不同的價格和包含不同的維生素,要以最低的總價格買到包含三種維生素ABC的果汁.

思路:

    明顯的一個線性dp求最優解,只是我們需要妥善處理ABC三種維生素這種不易編碼的信息,我建議基於二進制編碼ABC,比如101表示含有CA,111表示含有CBA,這樣的話只需要一個大小8的一維dp數組;

    然後由於二進制表示的是否含有某種維生素,故而我們可以 CA+CBA=CBA 我們就是101按位或111=111,完美搞定,而轉移方程:

                                              dp[i|j]=min(dp[i|j],dp[i]+dp[j]) (0<=i,j<=8)

 

AC代碼:

#include <stdio.h>
#define min(a,b) (a)<(b)?(a):(b)
const int inf=0x3f3f3f3f;
void solve(){
	int dp[8];
	for(int i=0;i<8;i++) dp[i]=inf;
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		int price;
		char vc[4];
		scanf("%d%s",&price,vc);
		int value=0,idx=0; //value爲轉換爲二進制之後的果汁維生素種類 
		while(vc[idx]) value|=(1<<(vc[idx++]-'A'));
		// 更新對應值 
		if(dp[value]>price) dp[value]=price;
	}
	// i|j 完美的完成了果汁維生素相加 
	for(int i=0;i<8;i++) for(int j=0;j<8;j++) dp[i|j]=min(dp[i|j],dp[i]+dp[j]);
	if(dp[7]==inf) printf("-1\n");
	else printf("%d",dp[7]);
}

int main(){
	solve();
	return 0;
}

B - Polycarp and Div 3

    Polycarp likes numbers that are divisible by 3.

    He has a huge number s. Polycarp wants to cut from it the maximum number of numbers that are divisible by 3. To do this, he makes an arbitrary number of vertical cuts between pairs of adjacent digits. As a result, after m such cuts, there will be m+1 parts in total. Polycarp analyzes each of the obtained numbers and finds the number of those that are divisible by 3.

    For example, if the original number is s=3121, then Polycarp can cut it into three parts with two cuts: 3|1|21. As a result, he will get two numbers that are divisible by 3.

    Polycarp can make an arbitrary number of vertical cuts, where each cut is made between a pair of adjacent digits. The resulting numbers cannot contain extra leading zeroes (that is, the number can begin with 0 if and only if this number is exactly one character '0'). For example, 007, 01 and 00099 are not valid numbers, but 90, 0 and 10001 are valid.

    What is the maximum number of numbers divisible by 3 that Polycarp can obtain?

Input

    The first line of the input contains a positive integer s. The number of digits of the number s is between 1 and 2*10^{5} , inclusive. The first (leftmost) digit is not equal to 0.

Output

    Print the maximum number of numbers divisible by 3

    that Polycarp can get by making vertical cuts in the given number s.

Examples

Input

3121

Output

2

Input

6

Output

1

Input

1000000000000000000000000000000000

Output

33

Input

201920181

Output

4

Note

    In the first example, an example set of optimal cuts on the number is 3|1|21.

    In the second example, you do not need to make any cuts. The specified number 6 forms one number that is divisible by 3.

    In the third example, cuts must be made between each pair of digits. As a result, Polycarp gets one digit 1 and 33 digits 0. Each of the 33 digits 0 forms a number that is divisible by 3.

    In the fourth example, an example set of optimal cuts is 2|0|1|9|201|81. The numbers 0, 9, 201 and 81 are divisible by 3.

 

題意:

    Polycarp喜歡能被3整除的數字。
    他有一個很大的數s,Polycarp想從中剪出儘可能多的能被3整除的數。爲此,他在相鄰數字對之間進行任意數量的垂直切割。因此,經過m個這樣的切割後,總共會有m+1個零件。Polycarp分析每個得到的數並找出數字之中能被3整除的數。

    例如,如果原始的數字是s=3121,那麼Polycarp可以把它分成三部分,分兩部分:3|1|21。結果,他得到兩個能被3整除的數。

    Polycarp可以進行任意數量的垂直切割,每個切割都在相鄰的兩個數字之間進行。結果數字不能包含額外的前導零(也就是說,當且僅當該數字恰好是一個字符“0”時,該數字可以以0開頭)。例如,007、01和00099不是有效的數字,但是90、0和10001是有效的數字。

    Polycarp能獲得的整除3的數字最多能有多少個?

思路:

    題目倒是很清晰,是要將這2e5大小的字符串切割成多個數字,最後能被3整除的最多能有多少個,簡而言之就是最優解問題.

    這裏考慮使用dp來統計,根據字符串位置進行狀態分劃使dp[i][j]表示字符串前i個字符子串切割出的最後一個數字求餘3爲i時能切割出的最多整除3的數字,這個dp設計的太醜了不建議學習,我繼續看看能不能優化再說吧,A是A了.

AC代碼:

#include <stdio.h>
#define max(a,b) (a)>(b)?(a):(b) 
const int maxs=2e5+5;
char str[maxs];

void solve(){
	scanf("%s",str);
	int dp[2][3];// dp[now][i]=x 表示後綴爲i的情況下最多可切出x個3的倍數,爲-1表示沒有後綴i的情況 
	dp[0][0]=0,dp[0][1]=dp[0][2]=-1;
	int idx=0,now=0;
	while(str[idx]){
		int now_number=str[idx]-'0',next=(now+1)%2;
		
		// 默認切斷 
		dp[next][0]=dp[now][0],dp[next][1]=dp[next][2]=-1;
		// 如果不切斷 
		for(int i=0;i<3;i++){
			if(dp[now][i]!=-1){
				if((i*10+now_number)%3) dp[next][(i*10+now_number)%3]=dp[now][i];
				else dp[next][0]=max(dp[next][0],dp[now][i]+1); 
			}
		}
		
		now=next;
		idx++;
	}
	printf("%d\n",dp[now][0]);
}

int main(){
	solve();
	return 0;
}

 

 

LSNU寒假第三場(數據結構)

比賽傳送門

A - A and B and Compilation Errors

    A and B are preparing themselves for programming contests.

    B loves to debug his code. But before he runs the solution and starts debugging, he has to first compile the code.

    Initially, the compiler displayed n compilation errors, each of them is represented as a positive integer. After some effort, B managed to fix some mistake and then another one mistake.

    However, despite the fact that B is sure that he corrected the two errors, he can not understand exactly what compilation errors disappeared — the compiler of the language which B uses shows errors in the new order every time! B is sure that unlike many other programming languages, compilation errors for his programming language do not depend on each other, that is, if you correct one error, the set of other error does not change.

    Can you help B find out exactly what two errors he corrected?

Input

The first line of the input contains integer n (3\leq n\leq 10^{5}) — the initial number of compilation errors.

The second line contains n space-separated integers a_{1},a_{2},....,a_{n} (1\leq a_{i}\leq 10^{9}) — the errors the compiler displayed for the first time.

The third line contains n - 1 space-separated integers b_{1},b_{2},....,b_{n-1} — the errors displayed at the second compilation. It is guaranteed that the sequence in the third line contains all numbers of the second string except for exactly one.

The fourth line contains n - 2 space-separated integers c_{1},c_{2},....,c_{n-2}— the errors displayed at the third compilation. It is guaranteed that the sequence in the fourth line contains all numbers of the third line except for exactly one.

Output

    Print two numbers on a single line: the numbers of the compilation errors that disappeared after B made the first and the second correction, respectively.

Examples

Input

5
1 5 8 123 7
123 7 5 1
5 1 7

Output

8
123

Input

6
1 4 3 3 5 7
3 7 5 4 3
4 3 7 5

Output

1
3

Note

    In the first test sample B first corrects the error number 8, then the error number 123.

    In the second test sample B first corrects the error number 1, then the error number 3. Note that if there are multiple errors with the same number, B can correct only one of them in one step.

題意:

    A和B正在爲編程比賽做準備。
    B喜歡調試他的代碼。但是在運行解決方案並開始調試之前,必須先編譯代碼。
    最初,編譯器顯示n個編譯錯誤,每個錯誤都表示爲正整數。經過一番努力,B終於改正了其中一個和另一個的錯誤。
然而,儘管B確信他改正了這兩個錯誤,但他不能確切地理解是什麼編譯錯誤消失了——B使用的語言的編譯器每次都以新順序顯示錯誤!B確信,與許多其他編程語言不同,他的編程語言的編譯錯誤並不相互依賴,也就是說,如果你糾正了一個錯誤,其他錯誤的集合也不會改變。
    你能幫B找出他到底改正了哪兩個錯誤嗎?

    總結題意就是現在給你n個代表編譯錯誤的數字(從樣例二可知數字可重複),已知每次修改改正一個錯誤,且錯誤之間無關聯,然後給你經過第一次修改之後以新順序顯示的n-1個數字,再給你經過第二次修改之後的以新順序顯示的n-2個數字,問被改正的這兩個錯誤的數字是多少?

思路:

    我們的目標就是要找到這n個數字和n-1個數字少的那一個數字,以及n-2個和n-1個相比少的那一個,然而由於數字順序打亂以及數字可能重複造成比較困難.

    由於本週是數據結構專題我們先討論數據結構解法,這道題可使用帶數目的二叉搜索樹完成,先將第二行的n個數字建立二叉搜索樹(紅黑樹最好,建議直接用map或mutiset),再將第三行的n-1個數字建立二叉搜索樹,遍歷輸出不同的結點即可,第四行的n-2個數字於第三行相同處理,此做法3*n*logn;

    也可對錯誤數字進行排序然後逐個比較,這樣的做法也是3*n*logn;

    我最建議的是通過異或運算以 n 複雜度做法完成這道題,由於修改前與修改後的所有數字只有一個數字相差,故而我們可知非被修改的數字修改前後個數加在一起一定是偶數個(比如修改前3個+修改後3個=6個),被修改的數字修改前後個數加在一起一定是奇數個,故而我們可直接將表示編譯報錯的數字全部異或在一起得到一個特徵值,修改前後的特徵值異或得到的就是被修改的數字.

AC代碼:

1.異或 O(n)

#include <stdio.h>

const int maxn=1e5;
void solve(){
	int n;
	scanf("%d",&n);
	int feature[3]; //feature[0]表示第一次所有報錯數字異或結果 
	for(int i=0;i<3;i++){
		feature[i]=0;
		for(int j=0;j<n-i;j++){
			int temp;
			scanf("%d",&temp);
			feature[i]^=temp;
		}
	}
	for(int i=1;i<3;i++) printf("%d\n",feature[i]^feature[i-1]);
}

int main(){
	solve();
	return 0;
}

2.map O(3*n*logn)

#include <stdio.h>
#include <map>
using namespace std;
const int maxn=1e5+5;
map<int,int> arr[3];
int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<3;i++){
		for(int j=0;j<n-i;j++){
			int num;
			scanf("%d",&num);
			arr[i][num]++;
		}
	}
	map<int,int>::iterator ite;
	for(int i=0;i<2;i++){
		for(ite=arr[i].begin();ite!=arr[i].end();ite++){
			if(!arr[i+1].count(ite->first)||ite->second!=arr[i+1][ite->first]){
				printf("%d\n",ite->first);
				break;
			}
		}
	}
	return 0;
}

 

B - Maximum Absurdity

    Reforms continue entering Berland. For example, during yesterday sitting the Berland Parliament approved as much as n laws (each law has been assigned a unique number from 1 to n). Today all these laws were put on the table of the President of Berland, G.W. Boosch, to be signed.

    This time mr. Boosch plans to sign 2k laws. He decided to choose exactly two non-intersecting segments of integers from 1 to n of length k and sign all laws, whose numbers fall into these segments. More formally, mr. Boosch is going to choose two integers a, b ( 1\leq a\leq b\leq n-k+1, b - a\geq k ) and sign all laws with numbers lying in the segments [aa + k - 1] and [bb + k - 1] (borders are included).

    As mr. Boosch chooses the laws to sign, he of course considers the public opinion. Allberland Public Opinion Study Centre (APOSC) conducted opinion polls among the citizens, processed the results into a report and gave it to the president. The report contains the absurdity value for each law, in the public opinion. As mr. Boosch is a real patriot, he is keen on signing the laws with the maximum total absurdity. Help him.

Input

    The first line contains two integers n and k (2\leq n\leq 2*10^{5}, 0 < 2k ≤ n) — the number of laws accepted by the parliament and the length of one segment in the law list, correspondingly. The next line contains n integers x_{1},x_{2},....x_{n} — the absurdity of each law (1\leq x_{i}\leq 10^{9} ).

Output

    Print two integers a, b — the beginning of segments that mr. Boosch should choose. That means that the president signs laws with numbers from segments [aa + k - 1] and [bb + k - 1]. If there are multiple solutions, print the one with the minimum number a. If there still are multiple solutions, print the one with the minimum b.

Examples

Input

5 2
3 6 1 1 6

Output

1 4

Input

6 2
1 1 1 1 1 1

Output

1 3

Note

    In the first sample mr. Boosch signs laws with numbers from segments [1;2] and [4;5]. The total absurdity of the signed laws equals 3 + 6 + 1 + 6 = 16.

    In the second sample mr. Boosch signs laws with numbers from segments [1;2] and [3;4]. The total absurdity of the signed laws equals 1 + 1 + 1 + 1 = 4.

 

題意:

   波蘭改革仍在進行。例如,在昨天的會議上,波蘭議會批准了多達n條法律(每一條法律都被分配了一個唯一的數字,從1到n),今天所有這些法律都被放在伯蘭的總統桌上,等待簽署。

    這一次,波蘭計劃簽署 2k 條法律。總統決定從1到n選擇兩個長度爲k的互不相交的區間,並簽署區間中所有的法律.更正式說,Boosch先生將選擇兩個整數a, b ( 1\leq a\leq b\leq n-k+1, b - a\geq k ),並簽署所有[a;a + k - 1]和[b;b + k - 1](包括邊框)中的所有法律。

    在Boosch選擇簽署法律的同時,他當然也會考慮公衆輿論。Allberland民意研究中心(APOSC)對市民進行了民意調查,並將結果整理成報告交給了總統。這份報告包含了在公衆眼中每一條法律的荒謬值。由於Boosch是一個真正的愛國者,他熱衷於簽署荒謬至極的法律。幫助他。

    總結題意就是現在有n個數字代表這n條法律的荒謬值,尋找兩個不相交的長度k的區間使得荒謬值總和最大,最後要輸出的就是這兩個長度k的區間的開始位置.

思路:

    我們需要找的是兩個不相交區間,這兩個區間區間和的和要儘可能大,首先長度爲k的區間總共有n-k+1個,比如n爲5,k爲2時,長度2的區間有[0,1],[1,2],[2,3],[3,4],我們大可以先預處理出這n-k+1個區間的區間和數組seg_sum,我們要找的是兩個區間且由於要求兩區間不交叉故而我們無法貪心,我們可以考慮枚舉第一個區間,然後第二個區間貪心的選取區間和最大的,

    例如若第一個區間從i開始,第二個區間從i+k開始貪心即可保證不會交叉,故而問題變爲尋找[i+k,n-k]個區間的區間和值中最大的數字

    區間最大值以線段樹輔助處理即可達到logn的查找效率,故而這將會是一個預處理n,枚舉第一個區間n-2k,線段樹查找第二個區間O(log(n-k))的總複雜度nlogn算法.

    然而由於這裏的區間和的值是不會變的,故而我們可以通過預處理出一個seg_max數組,seg_max[i]表示seg_sum中[i,n-k]的最大值下標,這樣的話查找第二個區間即可加速到O(1),進化爲總複雜度 n 算法.

AC代碼:

1.預處理 O(n)

#include <stdio.h>
#define max(a,b) (a)>(b)?(a):(b)
typedef long long ll;
const int maxn=2e5+5;
ll absurdity[maxn];

ll seg_sum[maxn];// 區間和數組,seg_sum[i]表示[i,i+k-1]的區間和 
ll seg_max[maxn];// 區間最大值數組,seg_max[i]表示seg_sum中[i,n-k]的最大值下標 


void solve(){
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) scanf("%I64d",&absurdity[i]);
	// 預處理區間和 seg_sum
	seg_sum[n-k]=0;
	for(int i=n-1;i>=n-k;i--) seg_sum[n-k]+=absurdity[i];
	for(int i=n-k-1;i>=0;i--) seg_sum[i]=seg_sum[i+1]+absurdity[i]-absurdity[i+k];
	
	// 根據區間和數組預處理 seg_max
	seg_max[n-k]=n-k;
	for(int i=n-k-1;i>=k;i--){
		if(seg_sum[i]>=seg_sum[seg_max[i+1]]) seg_max[i]=i;
		else seg_max[i]=seg_max[i+1];
	}
	
	//枚舉區間1起點,通過 seg_max 搜索區間2 
	int idx_1=0,idx_2=k;	 
	for(int i=0;i<=n-2*k;i++){
		int max_idx=seg_max[i+k];
		if(seg_sum[idx_1]+seg_sum[idx_2]<seg_sum[i]+seg_sum[max_idx]){
			idx_1=i;
			idx_2=max_idx;
		}
	}
	printf("%d %d\n",idx_1+1,idx_2+1);
}

int main(){
	solve();
	return 0;
} 

2.線段樹 O(nlogn)

#include <stdio.h>
typedef long long ll;
const int maxn=2e5+5;
ll absurdity[maxn];

ll seg_sum[maxn];// 區間和數組,seg_sum[i]表示[i,i+k-1]的區間和 
int st[maxn*3];//線段樹segment_tree,每個結點存的是對應區間最大值在原數組的下標 

//根據原數組seg_sum建樹 
void build(int q,int l,int r){
    if(l==r){ //遞歸到了葉子結點 
        st[q]=l;
        return;
    }
    int mid=(l+r)>>1; 
    build((q<<1)+1,l,mid); //建左子樹 
    build((q+1)<<1,mid+1,r);//建右子樹
    if(seg_sum[st[(q<<1)+1]]>=seg_sum[st[(q+1)<<1]]) st[q]=st[(q<<1)+1];
    else st[q]=st[(q+1)<<1];
} 

//查詢[tl,tr]區間最大值 
int query(int q,int l,int r,int tl,int tr) {
    if(tl<=l&&r<=tr) return st[q];
    int mid=(l+r)>>1,max_idx=-1;
    if(tl<=mid){
    	int temp=query((q<<1)+1,l,mid,tl,tr);
    	if(max_idx==-1||seg_sum[max_idx]<seg_sum[temp]) max_idx=temp;
    }
    if(tr>mid){
    	int temp=query((q+1)<<1,mid+1,r,tl,tr);
    	if(max_idx==-1||seg_sum[max_idx]<seg_sum[temp]) max_idx=temp;
    }
    return max_idx;
}


void solve(){
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) scanf("%I64d",&absurdity[i]);
	// 預處理區間和
	seg_sum[n-k]=0;
	for(int i=n-1;i>=n-k;i--) seg_sum[n-k]+=absurdity[i];
	for(int i=n-k-1;i>=0;i--) seg_sum[i]=seg_sum[i+1]+absurdity[i]-absurdity[i+k];
	
	// 根據區間和數組建立線段樹 
	build(0,0,n-k);
	
	//枚舉區間1起點,線段樹搜索區間2 
	int idx_1=0,idx_2=k;	 
	for(int i=0;i<=n-2*k;i++){
		int max_idx=query(0,0,n-k,i+k,n-k);
		if(seg_sum[idx_1]+seg_sum[idx_2]<seg_sum[i]+seg_sum[max_idx]){
			idx_1=i;
			idx_2=max_idx;
		}
	}
	printf("%d %d\n",idx_1+1,idx_2+1);
}

int main(){
	solve();
	return 0;
} 

C - Contest Balloons

codeforces題目傳送門

    One tradition of ACM-ICPC contests is that a team gets a balloon for every solved problem. We assume that the submission time doesn't matter and teams are sorted only by the number of balloons they have. It means that one's place is equal to the number of teams with more balloons, increased by 1. For example, if there are seven teams with more balloons, you get the eight place. Ties are allowed.

    You should know that it's important to eat before a contest. If the number of balloons of a team is greater than the weight of this team, the team starts to float in the air together with their workstation. They eventually touch the ceiling, what is strictly forbidden by the rules. The team is then disqualified and isn't considered in the standings.

    A contest has just finished. There are n teams, numbered 1 through n. The i-th team has ti balloons and weight wi. It's guaranteed that ti doesn't exceed wi so nobody floats initially.

    Limak is a member of the first team. He doesn't like cheating and he would never steal balloons from other teams. Instead, he can give his balloons away to other teams, possibly making them float. Limak can give away zero or more balloons of his team. Obviously, he can't give away more balloons than his team initially has.

    What is the best place Limak can get?

Input

    The first line of the standard input contains one integer n (2 ≤ n ≤ 300 000) — the number of teams.

    The i-th of n following lines contains two integers ti and wi (0 ≤ ti ≤ wi ≤ 10^{18}) — respectively the number of balloons and the weight of the i-th team. Limak is a member of the first team.

Output

    Print one integer denoting the best place Limak can get.

Examples

Input

8
20 1000
32 37
40 1000
45 50
16 16
16 16
14 1000
2 1000

Output

3

Input

7
4 4
4 4
4 4
4 4
4 4
4 4
5 5

Output

2

Input

7
14000000003 1000000000000000000
81000000000 88000000000
5000000000 7000000000
15000000000 39000000000
46000000000 51000000000
0 1000000000
0 0

Output

2

Note

    In the first sample, Limak has 20 balloons initially. There are three teams with more balloons (32, 40 and 45 balloons), so Limak has the fourth place initially. One optimal strategy is:

  1. Limak gives 6 balloons away to a team with 32 balloons and weight 37, which is just enough to make them fly. Unfortunately, Limak has only 14 balloons now and he would get the fifth place.
  2. Limak gives 6 balloons away to a team with 45 balloons. Now they have 51 balloons and weight 50 so they fly and get disqualified.
  3. Limak gives 1 balloon to each of two teams with 16 balloons initially.
  4. Limak has 20 - 6 - 6 - 1 - 1 = 6 balloons.
  5. There are three other teams left and their numbers of balloons are 40, 14 and 2.
  6. Limak gets the third place because there are two teams with more balloons.

    In the second sample, Limak has the second place and he can't improve it.

    In the third sample, Limak has just enough balloons to get rid of teams 2, 3 and 5 (the teams with 81 000 000 000, 5 000 000 000 and 46 000 000 000 balloons respectively). With zero balloons left, he will get the second place (ex-aequo with team 6 and team 7).

 

題意:

    ACM-ICPC競賽的一個傳統是一個隊伍每解決一個問題就得到一個氣球。我們假設提交時間無關緊要,隊伍只根據他們擁有的氣球數量排序。這意味着一支隊伍的排名等於有更多氣球的隊伍的數量,每支隊伍增加1。例如,如果有七支隊伍有比你更多的氣球,你將會是第八名。允許並列排名。
    你一定知道比賽前吃東西是很重要的。如果一個隊伍的氣球數量大於這個隊伍的總重量,這個隊伍將會和他們的比賽桌一起漂浮在空中。他們將觸及天花板,這是規則嚴格禁止的。隨後該隊將被取消資格,也不會被考慮進入積分榜。
    比賽剛剛結束。有n個隊,編號從1到n。第i個隊有ti氣球和wi重量。它保證ti不超過wi,所以沒有人一開始是浮動的。

   Limak是一隊的一員。他不喜歡作弊,也從不偷其他隊的氣球。相反,他可以把他的氣球送給其他隊伍,可能還可以讓它們漂浮起來。Limak可以送出他們隊伍所擁有的零或多個氣球。很明顯,他送出的氣球的數量不能多於他的團隊最初擁有的數量。

    Limak能得到的最好的排名是多少?

    總結題意就是現在有n個隊伍,每個隊伍已知氣球數和重量,第一支隊伍就是Limak所在的隊伍,最終排名僅僅根據氣球多的在前,相同則並列,特別的如果氣球數目多於隊伍重量則此隊伍不參與排名,Limak可將自己隊伍的部分氣球贈與其它隊伍,輸出Limak可拿到的最高排名.

思路:

    n個隊伍僅僅通過氣球數量排序,允許並列排名,就比如四支隊伍分別有2 2 2 1 個氣球,2 2 2三支隊伍並列第一,1在第四.

    在不考慮贈送氣球的情況下只需要基於氣球數目用sort降序排序後遍歷一遍即可知道limak是第幾名,可是現在允許贈送氣球以使得某些隊伍被取消排名資格,如果排名高於limak的隊伍被取消資格那麼limak的排名自然就上升了,所以我們需要考慮贈送氣球給哪個隊伍是最優的.

    大方向上自然是贈送給排名在limak之前(氣球數目比limak當前氣球多)的隊伍,然而贈送氣球之後自己擁有的氣球減少會使得排名高於limak的隊伍更多,因而我們自然是要贈送最少的氣球,故而我們使用一個優先隊列存所有氣球數比limak當前氣球數多的隊伍,根據"上天"需要消耗的最少氣球數比較大小.

    每次消滅一個"上天"消耗最少的隊伍,然後更新優先隊列,將新的比limak剩餘氣球數多的隊伍壓進優先隊列,之後優先隊列的長度+1自然就是limak隊伍的排名,因爲優先隊列裏面存的不就是所有比limak剩餘氣球數多的隊伍嗎,最優的排名一定會產生在這個不斷消滅隊伍的過程中.

AC代碼:

#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=3e5+5;

struct team{
	ll balloon_num;
	ll weight;
	bool operator>(const team &a)const{
		return weight-balloon_num>a.weight-a.balloon_num;
	}
}te[maxn];

bool comp(const team &a,const team &b){
	return a.balloon_num>b.balloon_num;
}

void solve(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%lld%lld",&te[i].balloon_num,&te[i].weight);
	
	// 根據氣球數量排序隊伍 
	sort(te+1,te+n,comp);
	
	// 存氣球數目大於Limak當前剩餘氣球的所有隊伍(未上天) 
	priority_queue<ll,vector<ll>,greater<ll> > min_que;
	// 初始化堆,上天消耗小的隊伍在前,idx記錄當前處理到了哪個隊伍 
	int idx=1;
	while(idx<n&&te[idx].balloon_num>te[0].balloon_num){
		min_que.push(te[idx].weight-te[idx].balloon_num+1);
		idx++;
	}
	
	// 不斷嘗試使排在前方的上天消耗最小的隊伍上天,上天之後更新大於當前剩餘氣球的隊伍 
	int highest_rank=min_que.size()+1;
	//隊列爲空(已第一) 或 可以使某個隊伍上天時 
	while(!min_que.empty()&&te[0].balloon_num>=min_que.top()){
		// 更新剩餘氣球
		te[0].balloon_num-=min_que.top();
		min_que.pop();
		// 更新堆,將新的比limak剩餘氣球多的隊伍壓入堆 
		while(idx<n&&te[idx].balloon_num>te[0].balloon_num){
			min_que.push(te[idx].weight-te[idx].balloon_num+1);
			idx++;
		}
		// 更新答案 
		if(highest_rank>min_que.size()+1) highest_rank=min_que.size()+1;
	}
	printf("%d\n",highest_rank);
}

int main(){
	solve();
	return 0;
}

D - Dense Subsequence

    You are given a string s, consisting of lowercase English letters, and the integer m.

    One should choose some symbols from the given string so that any contiguous subsegment of length m has at least one selected symbol. Note that here we choose positions of symbols, not the symbols themselves.

    Then one uses the chosen symbols to form a new string. All symbols from the chosen position should be used, but we are allowed to rearrange them in any order.

    Formally, we choose a subsequence of indices1\leq i_{1} < i_{2} < ... < i_{t} \leq \left | s \right | . The selected sequence must meet the following condition: for every j such that 1 ≤ j ≤ |s| - m + 1, there must be at least one selected index that belongs to the segment [j,  j + m - 1], i.e. there should exist a k from 1 to t, such thatj \leq i_{k} \leq j + m - 1.

    Then we take any permutation p of the selected indices and form a new string s_{i_{p_{1}}}s_{i_{p_{2}}}... s_{i_{p_{t}}}.

    Find the lexicographically smallest string, that can be obtained using this procedure.

Input

    The first line of the input contains a single integer m (1 ≤ m ≤ 100 000).

    The second line contains the string s consisting of lowercase English letters. It is guaranteed that this string is non-empty and its length doesn't exceed 100 000. It is also guaranteed that the number m doesn't exceed the length of the string s.

Output

    Print the single line containing the lexicographically smallest string, that can be obtained using the procedure described above.

Examples

Input

3
cbabc

Output

a

Input

2
abcab

Output

aab

Input

3
bcabcbaccba

Output

aaabb

Note

In the first sample, one can choose the subsequence {3} and form a string "a".

In the second sample, one can choose the subsequence {1, 2, 4} (symbols on this positions are 'a', 'b' and 'a') and rearrange the chosen symbols to form a string "aab".

題意:

    給定一個字符串s,由小寫英文字符組成,以及整數m。
    我們應該從給定的字符串中選擇一些字符,以便任何長度爲m的連續子段至少有一個選定的符號。注意,這裏我們選擇的是符號的位置,而不是符號本身。

    然後用選擇的符號形成一個新的字符串。應該使用所選位置的所有符號,但我們可以按任何順序重新排列它們。

    更正式的說,我們選擇的是某個子序列  1\leq i_{1} < i_{2} < ... < i_{t} \leq \left | s \right |  。選擇的順序必須符合以下條件:對於每個 1 ≤ j ≤ |s| - m + 1 的 j ,在( j, j + m - 1)必須有至少一個被選中的下標,即從1到t,應該存在一個k使得j \leq i_{k} \leq j + m - 1
    然後我們取所選索引的任意排列p,形成一個新的字符串 s_{i_{p_{1}}}s_{i_{p_{2}}}... s_{i_{p_{t}}}
    查找通過以上步驟可以獲得的按字典順序排列的最小字符串。

    總結題意就是從所給字符串中選取一部分字符,選出來的這部分字符要滿足兩個條件:

        1. 所有長度爲m的子段都包含至少一個被選出的字符,字符以位置區分,不同位置的a是不同的.

        2. 滿足條件1的前提下這些字符按字典順序排得到的字符串是所有方案中字典序最小的.

思路:

    一方面要字典序最小,一方面要滿足條件1,我們明白字典序是貪心的,我們考慮用貪心解決這個問題,長度爲m的子段總共 \left | s \right |-m+1 個.

    從左到右遍歷所有子段,每個子段若已包含一個已選取字符則pass,不包含則貪心選取子段中最小的字符即可.子段中最小字符,簡而言之就是區間最小值,用線段樹解決可達logn,故而總複雜度將會是nlogn

    線段樹不需要考慮修改只需要區間查詢功能,查詢得到的應該是區間最小字符的下標.

    這道題是最小字典序,要小心比如樣例三 

    3
    bcabcbaccba

    這個樣例應該是選取下標2,5,6,9 的字符組成aabb即可,然而我們大可以多選一個多餘的a構成aaabb使得字典序比aabb更小,故而噹噹前輸出的字符並非被選取字符中的最大字符時,原串中的此字符有多少個就得選多少個,以此保證字典序最小.

AC代碼:

#include <stdio.h>
const int maxm=1e5+5;

char s[maxm];
int st[maxm*3];//線段樹segment_tree,每個結點存的是對應區間最小字符在原數組的下標 

//根據原數組s建樹 
void build(int q,int l,int r){
    if(l==r){ //遞歸到了葉子結點 
        st[q]=l;
        return;
    }
    int mid=(l+r)>>1; 
    build((q<<1)+1,l,mid); //建左子樹 
    build((q+1)<<1,mid+1,r);//建右子樹
    if(s[st[(q<<1)+1]]<s[st[(q+1)<<1]]) st[q]=st[(q<<1)+1];
    else st[q]=st[(q+1)<<1];
} 

//查詢[tl,tr]區間最小字符下標,相同取靠後的 
int query(int q,int l,int r,int tl,int tr) {
    if(tl<=l&&r<=tr) return st[q];
    int mid=(l+r)>>1,min_idx=-1; 
    if(tl<=mid) min_idx=query((q<<1)+1,l,mid,tl,tr);
    if(tr>mid){
    	int temp=query((q+1)<<1,mid+1,r,tl,tr);
    	if(min_idx==-1||s[min_idx]>=s[temp]) min_idx=temp;
    }
    return min_idx;
}

void solve(){
	int m;
	scanf("%d%s",&m,s);
	// 測長度同時統計字符 
	int num[26];// num[i]=x表示原字符串中i+'a'有x個 
	for(int i=0;i<26;i++) num[i]=0;
	int len=0;
	while(s[len]) num[s[len++]-'a']++;
	// 建樹 
	build(0,0,len-1);
	
	int ans[26];// ans[i]=x表示被選中的字符中i+'a'有x個 
	for(int i=0;i<26;i++) ans[i]=0;
	int max_char=0;
	
	// 遍歷所有連續子段 
	int idx=0;
	while(idx<=len-m){
		// 區間查詢子段中求最小字符下標 
		int select_idx=query(0,0,len-1,idx,idx+m-1);
		// 根據選中的字符 s[select_idx] 更新ans及max_char 
		ans[s[select_idx]-'a']++;
		if(s[select_idx]-'a'>max_char) max_char=s[select_idx]-'a';
		// 跳躍優化 
		idx=select_idx+1;
	}
	// 輸出小於最大字符的字符時全部輸出 
	for(int i=0;i<max_char;i++) for(int j=0;j<num[i];j++) printf("%c",i+'a');
	for(int i=0;i<ans[max_char];i++) printf("%c",max_char+'a');
}

int main(){
	solve();
	return 0;
} 

E - Kostya the Sculptor

    Kostya is a genial sculptor, he has an idea: to carve a marble sculpture in the shape of a sphere. Kostya has a friend Zahar who works at a career. Zahar knows about Kostya's idea and wants to present him a rectangular parallelepiped of marble from which he can carve the sphere.

    Zahar has n stones which are rectangular parallelepipeds. The edges sizes of the i-th of them are ai, bi and ci. He can take no more than two stones and present them to Kostya.

    If Zahar takes two stones, he should glue them together on one of the faces in order to get a new piece of rectangular parallelepiped of marble. Thus, it is possible to glue a pair of stones together if and only if two faces on which they are glued together match as rectangles. In such gluing it is allowed to rotate and flip the stones in any way.

    Help Zahar choose such a present so that Kostya can carve a sphere of the maximum possible volume and present it to Zahar.

Input

    The first line contains the integer n ( 1\leq n\leq 10^{5}).

    n lines follow, in the i-th of which there are three integers ai, bi and ci (1\leq a_{i},b_{i},c_{i}\leq 10^{9}) — the lengths of edges of the i-th stone. Note, that two stones may have exactly the same sizes, but they still will be considered two different stones.

Output

    In the first line print k (1 ≤ k ≤ 2) the number of stones which Zahar has chosen. In the second line print k distinct integers from 1 to n — the numbers of stones which Zahar needs to choose. Consider that stones are numbered from 1 to n in the order as they are given in the input data.

    You can print the stones in arbitrary order. If there are several answers print any of them.

Examples

Input

6
5 5 5
3 2 4
1 4 1
2 1 3
3 2 4
3 3 4

Output

1
1

Input

7
10 7 8
5 10 3
4 2 6
5 5 5
10 2 8
4 2 1
7 7 7

Output

2
1 5

Note

    In the first example we can connect the pairs of stones:

  • 2 and 4, the size of the parallelepiped: 3 × 2 × 5, the radius of the inscribed sphere 1
  • 2 and 5, the size of the parallelepiped: 3 × 2 × 8 or 6 × 2 × 4 or 3 × 4 × 4, the radius of the inscribed sphere 1, or 1, or 1.5 respectively.
  • 2 and 6, the size of the parallelepiped: 3 × 5 × 4, the radius of the inscribed sphere 1.5
  • 4 and 5, the size of the parallelepiped: 3 × 2 × 5, the radius of the inscribed sphere 1
  • 5 and 6, the size of the parallelepiped: 3 × 4 × 5, the radius of the inscribed sphere 1.5

    Or take only one stone:

  • 1 the size of the parallelepiped: 5 × 5 × 5, the radius of the inscribed sphere 2.5
  • 2 the size of the parallelepiped: 3 × 2 × 4, the radius of the inscribed sphere 1
  • 3 the size of the parallelepiped: 1 × 4 × 1, the radius of the inscribed sphere 0.5
  • 4 the size of the parallelepiped: 2 × 1 × 3, the radius of the inscribed sphere 0.5
  • 5 the size of the parallelepiped: 3 × 2 × 4, the radius of the inscribed sphere 1
  • 6 the size of the parallelepiped: 3 × 3 × 4, the radius of the inscribed sphere 1.5

    It is most profitable to take only the first stone.

題意:

    Kostya是個和藹可親的雕刻家,他有個主意:把大理石雕刻成球形。Kostya有個同行叫Zahar。Zahar知道Kostya的想法,想送給他一個長方形的平行六面體,他可以用它來雕刻球體。

    Zahar有n塊石頭,都是長方形的平行六面體。其中第i個的邊長分別爲ai, bi, ci。他最多隻能拿兩塊石頭送給克斯特亞。

    如果Zahar拿了兩塊石頭,他應該把它們粘在一個面上,這樣才能得到一塊新的平行六面體的大理石。因此,當且僅當粘在一起的兩個面矩形匹配時,才能將一對石頭粘在一起。在這種粘合過程中,它可以以任何方式旋轉和翻轉石頭。

    幫助Zahar選擇這樣一個禮物,這樣Kostya就可以雕刻一個儘可能大的球體並把它送給Zahar。

    總結題意就是現在有n塊平行六面體,平行六面體其實就是長方體,已知每塊石頭的三邊長,我們要從這n個石頭中選一個或兩個出來,使得以選出來的石頭切割出來的球體有最大半徑,選了兩塊石頭必須某個面一樣,然後把兩塊石頭粘在一起.

思路:

    首先,只選一個石頭的情況很簡單,其實這就是個 短板效應 ,  邊長爲a,b,c的長方體雕刻出來的最大球體直徑其實就是abc中最短的邊.

    問題難在選兩個石頭的情況,這兩個石頭要能粘在一起(粘在一起的兩面要相同),所謂的兩面相同其實就是兩個邊長數值相同,我們難的是找到粘在一起之後新的三邊長最小值最大的情況.

    我們考慮枚舉第一個石頭,設此石頭三邊長爲a,b,c且a<=b<=c,我們有以下三種粘法:

        1.若取a,c面與另一個石塊粘在一起,則由於a,c不變,b可能被填補的更高,因爲a小於更加大的b,也小於c,最終ans==a,等於不粘

        2.若取a,b面與另一個石塊粘在一起,則由於a,b不變,c可能被填補的更高,因爲a小於b,也小於更加大的b,最終ans==a,等於不粘

        2.若取b,c面與另一個石塊粘在一起,則由於b,c不變,a可能被填補的更高,最終ans>=a

    經過分析我們知道a<=b<=c,選擇最大的bc兩個邊長組成的面與其他石頭相粘纔是有效的.故而對於被枚舉的每一個石頭,我們在其餘n-1個石頭中找到同樣有邊長bc的石頭中a最長的石頭與其粘連即可,然而如果單純遍歷會tle,故而我們使用map預處理所有石頭的粘連匹配情況.

    比如對於石頭 1 3 5我們就需要在map中壓入鍵爲(3,5)值爲1的鍵值對,對於新的石頭2 3 5,則更新鍵(3,5)的鍵值對的值爲2,實際編碼中map的值存的是下標idx,通過訪問數組sto[idx][0]得到值.

AC代碼:

#include <stdio.h>
#include <map>
#include <algorithm> 
using namespace std;
typedef long long ll;
const int maxn=1e5+5;

ll sto[maxn][3];
void solve(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld%lld%lld",&sto[i][0],&sto[i][1],&sto[i][2]);
		sort(sto[i],sto[i]+3);
	}
	map<pair<ll,ll>,int > match_map;
	map<pair<ll,ll>,int >::iterator ite;
	for(int i=1;i<=n;i++){
		ite=match_map.find(make_pair(sto[i][1],sto[i][2]));
		if(ite==match_map.end()) match_map.insert(make_pair(make_pair(sto[i][1],sto[i][2]),i));
		else if(sto[ite->second][0]<sto[i][0]) ite->second=i;
	}
	ll max_diameter=-1;
	int ans[2],ans_num;
	for(int i=1;i<=n;i++){
		ite=match_map.find(make_pair(sto[i][1],sto[i][2]));
		ll temp_diameter=min(min(sto[i][1],sto[i][2]),ite->second==i?sto[i][0]:sto[i][0]+sto[ite->second][0]);
		if(temp_diameter>max_diameter){
			max_diameter=temp_diameter;
			ans[0]=i; 
			if(ite->second==i) ans_num=1;
			else ans_num=2,ans[1]=ite->second;
		}
	}
	printf("%d\n%d",ans_num,ans[0]);
	for(int i=1;i<ans_num;i++) printf(" %d",ans[i]);
}

int main(){
	solve();
	return 0;
}

LSNU寒假第四場(圖論+搜索)

A - Cyclic Components

    You are given an undirected graph consisting of n vertices and m edges. Your task is to find the number of connected components which are cycles.

    Here are some definitions of graph theory.

    An undirected graph consists of two sets: set of nodes (called vertices) and set of edges. Each edge connects a pair of vertices. All edges are bidirectional (i.e. if a vertex a is connected with a vertex b, a vertex b is also connected with a vertex a ). An edge can't connect vertex with itself, there is at most one edge between a pair of vertices.

Two vertices u and v belong to the same connected component if and only if there is at least one path along edges connecting u and v.

    A connected component is a cycle if and only if its vertices can be reordered in such a way that:

  • the first vertex is connected with the second vertex by an edge,
  • the second vertex is connected with the third vertex by an edge,
  • ...
  • the last vertex is connected with the first vertex by an edge,
  • all the described edges of a cycle are distinct.

    A cycle doesn't contain any other edges except described above. By definition any cycle contains three or more vertices.

    There are 6 connected components, 2 of them are cycles: [7,10,16] and [5,11,9,15].

Input

    The first line contains two integer numbers n and m (1\leq n\leq 10^{5}, 0\leq m\leq 10^{5}) — number of vertices and edges.

    The following m lines contains edges: edge i is given as a pair of vertices vi, ui (1≤vi,ui≤n, ui≠vi). There is no multiple edges in the given graph, i.e. for each pair (vi,ui) there no other pairs (vi,ui) and (ui,vi) in the list of edges.

Output

    Print one integer — the number of connected components which are also cycles.

Examples

Input

5 4
1 2
3 4
5 4
3 5

Output

1

Input

17 15
1 8
1 12
5 11
11 9
9 15
15 5
4 13
3 13
4 3
10 16
7 10
16 7
14 3
14 4
17 6

Output

2

Note

    In the first example only component [3,4,5] is also a cycle.

    The illustration above corresponds to the second example.

 

題意:

    你得到一個由n個頂點和m條邊組成的無向圖。你的任務是找到循環連通塊的數量。

    下面是圖論的一些定義。

    無向圖由兩個集合組成:節點集(稱爲頂點)和邊集。每條邊連接一對頂點。所有的邊都是雙向的(也就是說,如果一個頂點a與另一個頂點b相連,那麼另一個頂點b也與另一個頂點a相連)。一條邊不能與自身相連,一對頂點之間最多只能有一條邊。

    當且僅當u和v之間有至少一條路徑相連時,兩個頂點u和v屬於同一連通塊。

    一個被連通塊是循環的,當且僅當它的頂點可以這樣重新排序:

  • 第一個頂點通過一條邊與第二個頂點相連,
  • 第二個頂點通過一條邊與第三個頂點相連,
  • ...
  • 最後一個頂點通過一條邊與第一個頂點相連,
  • 一個循環的所有邊都是不同的。

    除了上面描述的外,循環不包含任何其他邊。根據定義,任何循環都包含三個或更多的頂點。


    比如上圖,圖中共有6個連通分量,其中2個爲循環:[7,10,16]和[5,11,9,15]。

    總結題意就是給你一個n結點m邊的圖,讓你算出圖中的循環連通塊的個數,循環連通塊的意義如圖中例子.

思路:

    我們是要判斷無向圖中的循環連通塊個數,首先什麼是循環連通塊,首先由於是無向圖,連通塊中任意兩點要有路徑直接或間接相連,

至於循環就是1->2->3->4->1這種單鏈循環.

    注意題目中說明輸入不會包含1,2 2,1這種相同邊,也不會包含 1,1 這種自己連向自己的邊.

    我們經過研究可得到一個結論:在本題輸入條件下,若連通塊中所有結點度都爲2,則是循環的.

    利用這個結論,我們編碼時用鄰接表存圖,然後做一個標誌數組標誌每個點是否已被訪問,即可遍歷所有點,對未被訪問的點使用bfs去得到並標記他所在的連通塊即可,判斷此連通塊是否全部結點度爲2.

AC代碼:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn=2e5+5;
// 鄰接表 
vector<int> v[maxn];
vector<int>::iterator ite;
// bfs 
queue<int> que;
bool flag[maxn];// flag[i]=true 表示編號i的點還未被訪問

// 判斷pos所在連通塊是否所有結點度爲2 
bool check(int pos){
	bool res=true; 
	flag[pos]=false;
	que.push(pos);
	while(!que.empty()){
		int now=que.front();
		que.pop();
		if(v[now].size()!=2) res=false;
		for(ite=v[now].begin();ite!=v[now].end();ite++){
			if(flag[*ite]){
				flag[*ite]=false;
				que.push(*ite);
			}
		}
	}
	return res;
}

void solve(){
	int n,m,t1,t2;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>t1>>t2;
		v[t1].push_back(t2);
		v[t2].push_back(t1);
	}
	fill(flag+1,flag+n+1,true);
	int ans=0;
	// 遍歷所有連通塊 
	for(int i=1;i<=n;i++) if(flag[i]&&check(i)) ans++;
	cout<<ans<<endl;
}


int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	solve();
	return 0;
}

 

B - Fight Against Traffic

    Little town Nsk consists of n junctions connected by m bidirectional roads. Each road connects two distinct junctions and no two roads connect the same pair of junctions. It is possible to get from any junction to any other junction by these roads. The distance between two junctions is equal to the minimum possible number of roads on a path between them.

    In order to improve the transportation system, the city council asks mayor to build one new road. The problem is that the mayor has just bought a wonderful new car and he really enjoys a ride from his home, located near junction s to work located near junction t. Thus, he wants to build a new road in such a way that the distance between these two junctions won't decrease.

    You are assigned a task to compute the number of pairs of junctions that are not connected by the road, such that if the new road between these two junctions is built the distance between s and t won't decrease.

Input

    The firt line of the input contains integers n, m, s and t (2 ≤ n ≤ 1000, 1 ≤ m ≤ 1000, 1 ≤ s, t ≤ n, s ≠ t) — the number of junctions and the number of roads in Nsk, as well as the indices of junctions where mayors home and work are located respectively. The i-th of the following m lines contains two integers u_{i} and v_{i} (1 ≤ u_{i}, v_{i}≤ n, u_{i}≠ v_{i} ), meaning that this road connects junctions ui and vi directly. It is guaranteed that there is a path between any two junctions and no two roads connect the same pair of junctions.

Output

    Print one integer — the number of pairs of junctions not connected by a direct road, such that building a road between these two junctions won't decrease the distance between junctions s and t.

Examples

Input

5 4 1 5
1 2
2 3
3 4
4 5

Output

0

Input

5 4 3 5
1 2
2 3
3 4
4 5

Output

5

Input

5 6 1 5
1 2
1 3
1 4
4 5
3 5
2 5

Output

3

題意:

    小鎮Nsk由n個路口組成,由m條雙向道路連接。每條道路連接兩個不同的路口,沒有兩條道路連接同一對路口。從任何一個路口到另一個路口都可以走這條路。兩個路口之間的距離等於它們之間道路上可能的最小道路數。
    爲了改善交通系統,市議會要求市長修一條新路。問題是,市長剛買了一個很棒的新汽車,他很喜歡從他在結點s旁邊的家開車到結點t附近工作。因此,他想要建立一個新的道路,但這兩個結點之間的距離不會減少。
    你被分配了一項任務來計算沒有被道路連接的路口對的數量,這樣如果在這兩個路口之間建立了新的道路,s和t之間的距離就不會減少。

    總結題意就是n個結點m條邊的無向圖,邊權都是1,現在想新建一條邊,問使得指定的兩點s,t最短距離不變的新建方案有多少種,不存在連接相同兩點的邊.

思路:

    我們可以分別以s和t爲起點進行兩次單源最短路徑,然後將連接t1,t2可能造成更短路徑的情況分爲三段,s到t1+t1到t2+t2到t或者s到t2+t2到t1+t1到t,枚舉所有的t1,t2,通過之前求好的最短路徑判斷是否更短.

AC代碼:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int max_v=1e3+5;
const int max_e=1e3+5;
const int inf=0x3f3f3f3f;
//beelman_ford比爾曼—福特算法  允許負邊的存在 
struct edge{
	int from,to,cost;
	edge(){}
	edge(int t_f,int t_t,int t_c):from(t_f),to(t_t),cost(t_c){}
}es[max_e*2];

int d_s[max_v],d_t[max_v];
int v,e;
void bellman_ford(int s,int d[]){
	for(int i=1;i<=v;i++) d[i]=inf;
	d[s]=0;
	while(true){
		bool update=true;
		for(int i=0;i<e;i++){
			if(d[es[i].from]!=inf&&d[es[i].to]>d[es[i].from]+es[i].cost){
				d[es[i].to]=d[es[i].from]+es[i].cost;
				update=false;
			}
		}
		if(update) break;
	}
}

void solve(){
	int s,t;
	scanf("%d%d%d%d",&v,&e,&s,&t);
	int t1,t2;
	for(int i=0;i<e;i++){
		scanf("%d%d",&t1,&t2);
		es[i*2]=edge(t1,t2,1);
		es[i*2+1]=edge(t2,t1,1);
	}
	e=e*2;
	// 兩次單源最短路
	bellman_ford(s,d_s);
	bellman_ford(t,d_t);
	// 枚舉所有點對
	int ans=0;
	for(int i=1;i<=v;i++) for(int j=i+1;j<=v;j++) if(d_s[i]+d_t[j]+1>=d_s[t]&&d_s[j]+d_t[i]+1>=d_s[t]) ans++; 
	printf("%d\n",ans-e/2);
}


int main(){
	solve();
	return 0;
}

 

C - Love Rescue

    Valya and Tolya are an ideal pair, but they quarrel sometimes. Recently, Valya took offense at her boyfriend because he came to her in t-shirt with lettering that differs from lettering on her pullover. Now she doesn't want to see him and Tolya is seating at his room and crying at her photos all day long.

    This story could be very sad but fairy godmother (Tolya's grandmother) decided to help them and restore their relationship. She secretly took Tolya's t-shirt and Valya's pullover and wants to make the letterings on them same. In order to do this, for one unit of mana she can buy a spell that can change some letters on the clothes. Your task is calculate the minimum amount of mana that Tolya's grandmother should spend to rescue love of Tolya and Valya.

    More formally, letterings on Tolya's t-shirt and Valya's pullover are two strings with same length n consisting only of lowercase English letters. Using one unit of mana, grandmother can buy a spell of form (c1, c2) (where c1 and c2 are some lowercase English letters), which can arbitrary number of times transform a single letter c1 to c2 and vise-versa on both Tolya's t-shirt and Valya's pullover. You should find the minimum amount of mana that grandmother should spend to buy a set of spells that can make the letterings equal. In addition you should output the required set of spells.

Input

    The first line contains a single integer n (1 ≤ n ≤ 105) — the length of the letterings.

    The second line contains a string with length n, consisting of lowercase English letters — the lettering on Valya's pullover.

    The third line contains the lettering on Tolya's t-shirt in the same format.

Output

    In the first line output a single integer — the minimum amount of mana t required for rescuing love of Valya and Tolya.

    In the next t lines output pairs of space-separated lowercase English letters — spells that Tolya's grandmother should buy. Spells and letters in spells can be printed in any order.

    If there are many optimal answers, output any.

Examples

Input

3
abb
dad

Output

2
a d
b a

Input

8
drpepper
cocacola

Output

7
l e
e d
d c
c p
p o
o r
r a

Note

    In first example it's enough to buy two spells: ('a','d') and ('b','a'). Then first letters will coincide when we will replace letter 'a' with 'd'. Second letters will coincide when we will replace 'b' with 'a'. Third letters will coincide when we will at first replace 'b' with 'a' and then 'a' with 'd'.

 

題意:

    Valya和Tolya是理想的一對,但他們有時也會吵架。最近,Valya對她的男朋友很生氣,因爲他穿的t恤上的字和她套頭衫上的字不一樣。現在她不想見他,Tolya整天坐在他的房間裏,對着她的照片哭泣。
    這個故事可能是非常悲傷的,但仙女教母(Tolya的祖母)決定幫助他們,恢復他們的關係。她偷偷拿走了Tolya的t恤和Valya的套衫,想把上面的字母拼在一起。爲了做到這一點,她可以用一個單位的魔法買一個可以改變衣服上一些字母的咒語。你的任務是計算出Tolya的祖母應該花費的最小法力值來拯救Tolya和Valya的愛。
    更正式的說法是,Tolya的t恤和Valya的套衫上的字母是兩根長度相同的字符串,只有小寫的英文字母。使用一個單位的魔法,祖母可以買一個形式的咒語(c1, c2)(其中c1和c2是一些小寫的英文字母),它可以任意次數地將一個字母c1轉換成c2,反之亦然。你應該找到祖母應該花的最小的魔法值來買一套咒語,使字母相等。此外,你應該輸出所需的法術。

    總結題意就是現在有兩個長度相同的字符串,我們可以使用魔法值購買咒語,一個魔法值購買的一條咒語,可以使用無限次的將一個單字符c1轉換成c2,反之也可以將c2轉換成c1,問將兩個字符串變爲一模一樣最少要花多少魔法值買咒語.

思路:

    這裏我們的咒語是核心,因爲 c1,c2 咒語能無限次並且也可雙向使用,c1->c2也可c2->c1,故而若有咒語 a,b 與 b,c 我們相當於也有了咒語a,c ,咒語是具有傳遞性的.

    既然是具有傳遞性的,我們就可以把26個小寫字母看作並查集中的基礎元素,同一集合內的字符自然可以任意互轉.

    我們只要遍歷字符串,在兩字符串中對應字符不同時,若兩字符在並查集中已是同一集合,自然不必再買咒語,若不同則購買,在購買咒語c1,c2之後就可以將c1,c2所在集合合併.

AC代碼:

#include <stdio.h>
const int maxn=1e5+5;
char valya[maxn],tolya[maxn];
int ans[maxn][2],ansnum=0;
int par[26]; 
void init(int n){  //初始化
    for(int i=0;i<n;i++) par[i]=i;  
}  

int find(int x){  //查找x所在集合的根
    if(par[x]!=x) par[x]=find(par[x]);//遞歸返回的同時壓縮路徑
    return par[x];  
}  
  
void unite(int x,int y){  //合併x與y所在集合
    x=find(x);  
    y=find(y);  
    par[x]=y; 
}  

bool same(int x,int y){  //x與y在同一集合則返回真
    return find(x)==find(y);  
} 


void solve(){
	int n;
	scanf("%d%s%s",&n,valya,tolya);
	init(26);
	int len=0;
	while(valya[len]){
		if(valya[len]!=tolya[len]&&!same(valya[len]-'a',tolya[len]-'a')){
			unite(valya[len]-'a',tolya[len]-'a');
			ans[ansnum][0]=valya[len],ans[ansnum][1]=tolya[len];
			ansnum++;
		}
		len++;
	}
	printf("%d\n",ansnum);
	for(int i=0;i<ansnum;i++) printf("%c %c\n",ans[i][0],ans[i][1]);
}


int main(){
	solve();
	return 0;
}

 

 

LSNU寒假第五場(數論)

A - The Wall (medium)

Heidi the Cow is aghast: cracks in the northern Wall? Zombies gathering outside, forming groups, preparing their assault? This must not happen! Quickly, she fetches her HC2 (Handbook of Crazy Constructions) and looks for the right chapter:

How to build a wall:

  1. Take a set of bricks.
  2. Select one of the possible wall designs. Computing the number of possible designs is left as an exercise to the reader.
  3. Place bricks on top of each other, according to the chosen design.

This seems easy enough. But Heidi is a Coding Cow, not a Constructing Cow. Her mind keeps coming back to point 2b. Despite the imminent danger of a zombie onslaught, she wonders just how many possible walls she could build with up to n bricks.

A wall is a set of wall segments as defined in the easy version. How many different walls can be constructed such that the wall consists of at least 1 and at most n bricks? Two walls are different if there exist a column c and a row r such that one wall has a brick in this spot, and the other does not.

Along with n, you will be given C, the width of the wall (as defined in the easy version). Return the number of different walls modulo 10^{6}+3.

Input

    The first line contains two space-separated integers n and C, 1 ≤ n ≤ 500000, 1 ≤ C ≤ 200000.

Output

    Print the number of different walls that Heidi could build, modulo 10^{6}+3.

Examples

Input

5 1

Output

5

Input

2 2

Output

5

Input

3 2

Output

9

Input

11 5

Output

4367

Input

37 63

Output

230574

Note

The number 10^{6}+3 is prime.

In the second sample case, the five walls are:

            B        B
B., .B, BB, B., and .B

In the third sample case, the nine walls are the five as in the second sample case and in addition the following four:

B    B
B    B  B        B
B., .B, BB, and BB

 

題意:

    奶牛海蒂驚呆了:北邊城牆上的裂縫?殭屍們聚集在外面,形成羣體,準備攻擊?這絕不能發生!很快,她拿起她的HC2(瘋狂建築手冊),尋找對應的章節:
    如何建造一堵牆:

  1. 取一組磚塊。
  2. 選擇一種可能的牆壁設計。計算可能的設計數量留給讀者作爲練習。
  3. 根據所選擇的設計,將磚塊放在彼此的頂部。

    這似乎很簡單。但海蒂是一頭會編碼的牛,不是一頭會建築的牛。她的思緒總是回到第二點。儘管殭屍攻擊的危險迫在眉睫,她想知道她能用最多n塊磚建多少堵牆。
    簡單的說一堵牆就是一段段牆的集合,有多少種不同的牆是由至少1個和最多n個磚塊組成的?如果存在c列和r列一面牆在這裏有一塊磚,而另一面牆沒有磚,那麼兩面牆是不同的。

    與n一起,你將得到C,即牆的寬度(如簡易版中定義的那樣)。以10^{6}+3爲模數,返回不同牆體的數量。

思路:

AC代碼:

 

B - Selection of Personnel

    One company of IT City decided to create a group of innovative developments consisting from 5 to 7 people and hire new employees for it. After placing an advertisment the company received n resumes. Now the HR department has to evaluate each possible group composition and select one of them. Your task is to count the number of variants of group composition to evaluate.

Input

    The only line of the input contains one integer n (7 ≤ n ≤ 777) — the number of potential employees that sent resumes.

Output

    Output one integer — the number of different variants of group composition.

Examples

Input

7

Output

29

 

題意:


    IT城的一家公司決定創建一個由5到7人組成的創新開發團隊,併爲其僱傭新員工。這家公司登廣告後,收到了n份簡歷。現在,人力資源部門必須評估每一個可能的團隊組成,並從中選擇一個。你的任務是計算要評估的組組成變量的數量。

    總結題意就是從n個人中選5到7個人問有幾種組合.

思路:

    後文用ull表示unsinged long long

    答案就是 C_{n}^{5}+C_{n}^{6}+C_{n}^{7} ,核心難點在於n最大777,777^{7}會爆掉ull,故而建議用大數處理(java bignumber歡迎你)計算.

    然而因爲題目中的最終答案最大大約是777^{7}/7! 這個答案是在 ull 以內的,故而推斷這道題可以卡量級.

    我們來分析組合數的公式: C_{n}^{m}=\frac{n!}{(n-m)!*m!} 可以簡化爲C_{n}^{m}=\frac{n*(n-1)*(n-2)....*(n-m+1)}{m!}

    核心在於分子乘完之後再除m!會爆掉,我們已知組合數的分子分母必然能整除,故而我們將分子分爲大小相近在ull之內的兩個,分別除以部分的分子再相乘以此確保不爆掉,我的做法是取前四個作爲前半段,用gcd確定分母怎麼分配.

1.卡量級

#include <stdio.h>
typedef unsigned long long ull;
ull gcd(ull a,ull b){
	if(b==0) return a;
	return gcd(b,a%b);
}
int main(){
	ull n;
	scanf("%llu",&n);
	
	ull ans=0,gcdres,temp=n*(n-1)*(n-2)*(n-3);
	
	gcdres=gcd(temp,120);
	ans+=(temp/gcdres)*((n-4)/(120/gcdres));
	
	gcdres=gcd(temp,720);
	ans+=(temp/gcdres)*((n-4)*(n-5)/(720/gcdres));
	
	gcdres=gcd(temp,5040);
	ans+=(temp/gcdres)*((n-4)*(n-5)*(n-6)/(5040/gcdres));
	
	printf("%llu",ans);
	return 0;
}

2.java 大數

 

C - New Year and the Sphere Transmission

    There are n people sitting in a circle, numbered from 1 to n in the order in which they are seated. That is, for all i from 1 to n−1, the people with id i and i+1 are adjacent. People with id n and 1 are adjacent as well.

    The person with id 1 initially has a ball. He picks a positive integer k at most n, and passes the ball to his k-th neighbour in the direction of increasing ids, that person passes the ball to his k-th neighbour in the same direction, and so on until the person with the id 1 gets the ball back. When he gets it back, people do not pass the ball any more.

    For instance, if n=6 and k=4, the ball is passed in order [1,5,3,1].

    Consider the set of all people that touched the ball. The fun value of the game is the sum of the ids of people that touched it. In the above example, the fun value would be 1+5+3=9.

    Find and report the set of possible fun values for all choices of positive integer k. It can be shown that under the constraints of the problem, the ball always gets back to the 1-st player after finitely many steps, and there are no more than 10^{5} possible fun values for given n.

Input

    The only line consists of a single integer n (2≤n≤10^{9} ) — the number of people playing with the ball.

Output

    Suppose the set of all fun values is f1,f2,…,fm.Output a single line containing m space separated integers f1 through fm in increasing order.

Examples

Input

6

Output

1 5 9 21

Input

16

Output

1 10 28 64 136

Note

In the first sample, we've already shown that picking k=4 yields fun value 9, as does k=2. Picking k=6 results in fun value of 1. For k=3 we get fun value 5 and with k=1 or k=5 we get 21.

In the second sample, the values 1, 10, 28, 64 and 136 are achieved for instance for k=16, 8, 4, 10 and 11, respectively.

 

題意:

    有n個人坐成一個圈,按他們坐的順序從1到n編號。也就是說,對於從1到n - 1的所有i, id爲i和i+1的是相鄰的。id爲n和1的人也相鄰。

    id爲1的人最初有一個球。他選擇一個正整數k,最多n,然後把球傳給他的第k個鄰居,這個人把球傳給他的第k個鄰居,同樣的方向,以此類推,直到id爲1的人把球拿回來。當他拿回球時,人們不再傳球了。

    例如,如果n=6, k=4,球按[1,5,3,1]的順序傳遞。

    考慮所有觸球的人的集合。遊戲的樂趣價值是觸摸它的人的id的總和。在上面的例子中,有趣的值是1+5+3=9。

    發現並報告所有的選擇可能有趣的設置值的正整數k。它可以表明,在問題的約束下,球總是回到1日球員有限許多步驟之後,給定的n的有趣值不會超過 10^{5}

    總結題意就是我們的球在n個從1到n編號的人手中傳遞球,可以選擇隔着k(n以內)個人傳,傳回1手上時經過的所有人的編號之和就是本次傳球的有趣值,從小到大輸出所有可能的有趣值.

思路:

    首先既然球能傳回1號手上,那麼這個k就是受到了n約束的,即必須是n的因數,或者是0或6,因而我們使用優化之後的遍歷方法O(根號n)的遍歷n的因數然後把每個因數下得到的有趣值存入set最後輸出即可.

    至於因數爲x時的有趣值,我們可以把經過的人的編號看作一個等差數列,這個等差數列有n/x項,首項爲1,公差爲x,用求和公式即可完成有趣值求取.我的代碼中關於等差數列求和公式是經過化簡之後的結果.

AC代碼:

#include <stdio.h>
#include <math.h>
#include <set>
using namespace std;
typedef long long ll;
int main(){
	ll n;
	scanf("%lld",&n);
	set<ll> ans;
	set<ll>::iterator ite;
	ans.insert(1); 
	for(int i=1;i<=sqrt(n);i++) if(n%i==0){
		// 步長爲i,n/i步 
		ans.insert(n/i+n*(n/i-1)/2);
		// 步長爲n/i,i步 
		ans.insert(i+(i-1)*n/2);
	} 
	printf("%lld",*ans.begin());
	for(ite=++ans.begin();ite!=ans.end();ite++) printf(" %lld",*ite);
	return 0;
}

 

 

D - Social Circles

    You invited nguests to dinner! You plan to arrange one or more circles of chairs. Each chair is going to be either occupied by one guest, or be empty. You can make any number of circles.

    Your guests happen to be a little bit shy, so the i-th guest wants to have a least li free chairs to the left of his chair, and at least ri free chairs to the right. The "left" and "right" directions are chosen assuming all guests are going to be seated towards the center of the circle. Note that when a guest is the only one in his circle, the li chairs to his left and ri chairs to his right may overlap.

    What is smallest total number of chairs you have to use?

Input

    First line contains one integer n — number of guests, (1⩽n⩽10^{5}).

    Next n lines contain n pairs of space-separated integers li and ri (0⩽li,ri⩽10^{9}).

Output

    Output a single integer — the smallest number of chairs you have to use.

Examples

Input

3
1 1
1 1
1 1

Output

6

Input

4
1 2
2 1
3 5
5 3

Output

15

Input

1
5 6

Output

7

Note

    In the second sample the only optimal answer is to use two circles: a circle with 5

    chairs accomodating guests 1 and 2, and another one with 10 chairs accomodationg guests 3 and 4.

    In the third sample, you have only one circle with one person. The guest should have at least five free chairs to his left, and at least six free chairs to his right to the next person, which is in this case the guest herself. So, overall number of chairs should be at least 6+1=7.

 

題意:

    你邀請了n個客人來吃飯!您計劃安排一個或多個圍成圈的椅子。每把椅子不是坐一個客人,就是空着。你可以做出任意數量的圓。

    您的客人剛好有點害羞,所以第i位客人想要至少有 l_{i} 把空椅子在他椅子的左邊,至少有 r_{i} 把空椅子在右邊。選擇“左”和“右”的方向時假設所有的客人都坐來面向圓心。注意當客人是他圈子裏唯一的人時,他左邊的li椅和他右邊的ri椅可能重疊。

    你需要使用的椅子的最小總數是多少?

    總結題意就是現在有n個客人來吃飯,每個客人都要求左右分別必須有li,ri個空位,現在要安排這n個客人坐下來,可以圍成任意多個圈,問需要最少幾把椅子?

思路:

    最劣情況是每個客人自己圍成一圈,然後在這個基礎上將r值與l值最相近的客人安排來合成一個圈即可達到最優的節約椅子,並且我們將比如客人a的右邊安排客人b並不會影響我們對於客人a左邊相鄰客人的選擇,左邊依舊選取最優抉擇.

    故而我們可知這是一個貪心的匹配l,r值的問題,我們可將所有的l,r值排序後依次配對,即是最優答案.

AC代碼:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll l[maxn],r[maxn];
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>l[i]>>r[i];
	
	ll ans=0;
	sort(l,l+n);
	sort(r,r+n);
	for(int i=0;i<n;i++) ans+=max(l[i],r[i])+1; 
	cout<<ans<<endl;
	return 0;
}

 

E - Enlarge GCD

    Mr. F has n positive integers,a_{1},a_{2},...,a_{n}.

    He thinks the greatest common divisor of these integers is too small. So he wants to enlarge it by removing some of the integers.

    But this problem is too simple for him, so he does not want to do it by himself. If you help him, he will give you some scores in reward.

    Your task is to calculate the minimum number of integers you need to remove so that the greatest common divisor of the remaining integers is bigger than that of all integers.

Input

    The first line contains an integer n (2\leq n\leq 3*10^{5} ) — the number of integers Mr. F has.

    The second line contains nintegers, a1,a2,…,an (1\leq a_{i}\leq 1.5*10^{7}).

Output

    Print an integer — the minimum number of integers you need to remove so that the greatest common divisor of the remaining integers is bigger than that of all integers.

    You should not remove all of the integers.

    If there is no solution, print «-1» (without quotes).

Examples

Input

3
1 2 4

Output

1

Input

4
6 9 15 30

Output

2

Input

3
1 1 1

Output

-1

Note

    In the first example, the greatest common divisor is 1 in the beginning. You can remove 1 so that the greatest common divisor is enlarged to 2. The answer is 1.

    In the second example, the greatest common divisor is 3 in the beginning. You can remove 6 and 9 so that the greatest common divisor is enlarged to 15. There is no solution which removes only one integer. So the answer is 2.

    In the third example, there is no solution to enlarge the greatest common divisor. So the answer is −1.

 

題意:

    F先生有n個正整數,a_{1},a_{2},...,a_{n}

    他認爲這些整數的最大公因數太小了。所以他想通過移除一些整數來放大它。

    但是這個問題對他來說太簡單了,所以他不想自己做。如果你幫助他,他會給你一些分數作爲獎勵。

    您的任務是計算需要刪除的最小整數數量,以便剩餘整數的最大公因數大於所有整數的最大公因數。

    總結題意就是要刪除最少的數字使得剩餘數字的最大公因數比原來n個數字的最大公因數更大.

思路:

    我們目的是刪除最少的數字使得剩餘數字的最大公因數d2比原來n個數字的最大公因數d1更大.

    那麼我們有一個最直觀的思路就是對這n個數字除以d1的結果分別做因數分解,統計因數的出現情況,統計出現最多的那個即爲我們的d2,因爲他出現最多所以刪除最少數字就能成爲公因數.

    那麼因數分解我們如果採用複雜度爲O(\sqrt{n})的試除法,由於數字最大15e6,單個數字因數分解複雜度4e3,數字總共3e5個,總複雜度會在12e8附近,預測會TLE.這裏我們可以考慮使用O(n^{\frac{1}{4}})的pollar_rho算法進行效率優化,或者使用像我以下的做法.

    題目沒有要求輸出刪除後的最大公因數,僅要求輸出最少刪除多少個,故而我們可以從這裏下手優化.

    首先我們需要了解唯一分解定理:大於1的合數都可以分解爲有限個質數的乘積.  故而我們假設若d2是一個合數,出現了x次,是出現最多的,那麼他也可以分解爲多個質數的乘積,而這些質數他們在n個數字中一定也剛好出現了x次,不多不少,不少是因爲這些質數作爲d2的因數,光d2就出現了x次,而不多是因爲如果多於x次則和d2的出現最多不就自相矛盾了嗎.

    故而我們僅僅需要進行質因數分解,出現最多的質因數必然是d2的因數,他的出現次數就是d2的出現次數,雖然我們並不知道這個d2到底是多少.而質因數分解通過歐拉篩法預處理質數,考慮到因數是成對的,我們只用處理\sqrt{15e6}以內的質因數出現情況即可,\sqrt{15e6}以內因數大概1e3個,故而最低效率會在3e5*1e3=3e8左右,加上一些優化已經可以接受.

    這裏要額外提到若試除了\sqrt{15e6}以內的質因數之後結果仍然不爲1說明剩下的這個數字本身是一個[\sqrt{15e6},15e6]以內的質數,這個要額外處理.15e6這個數據大小是可以開數組的,故而我們可以通過一個15e6大小的數組來存質因數的出現情況.

AC代碼:

#include <stdio.h>
#include <math.h>
typedef long long ll;
const int maxn=3e5+5;
const int maxa=15e6+5;
int a[maxn];

int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}

bool vis[4005];
int prime[4005],cnt;
void euler(int t){// 歐拉篩法
	for(int i=2;i<=t;i++) vis[i]=true;
	cnt=0;
	for(int i=2;i<=t;i++){
		if(vis[i]) prime[cnt++]=i;
		for(int j=0;j<cnt&&i*prime[j]<=t;j++){
			vis[i*prime[j]]=false;
			if(i%prime[j]==0) break;
		}
	}
}

int ans[maxa];

int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	
	int gcd_res=a[0];// 原最大公因數
	for(int i=1;i<n;i++) gcd_res=gcd(gcd_res,a[i]);

	euler(sqrt(maxa));
	for(int i=0;i<n;i++){ // 質因數分解
		a[i]/=gcd_res;
		for(int j=0;j<cnt&&prime[j]*prime[j]<=a[i];j++){ // 試除法
			if(a[i]%prime[j]==0) ans[prime[j]]++;
			while(a[i]%prime[j]==0)	a[i]/=prime[j];
		}
		if(a[i]!=1) ans[a[i]]++;// 最後依舊爲1說明剩下的a[i]是個質數
	}
	int tmax=0;
	for(int i=2;i<maxa;i++) if(tmax<ans[i]) tmax=ans[i]; 
	if(tmax==0) printf("-1\n");
	else printf("%d\n",n-tmax);
	return 0;
}

G - Remainders Game

    Today Pari and Arya are playing a game called Remainders.

    Pari chooses two positive integer x and k, and tells Arya k but not x. Arya have to find the value . There are n ancient numbersc_{1},c_{2},...,c_{n} and Pari has to tell Arya x mod c_{i} if Arya wants. Given k and the ancient values, tell us if Arya has a winning strategy independent of value of x or not. Formally, is it true that Arya can understand the value x mod k for any positive integer x?

    Note, that x mod y means the remainder of x after dividing it by y.

Input

    The first line of the input contains two integers n and k (1\leq n,k\leq 1e6) — the number of ancient integers and value k that is chosen by Pari.

    The second line contains n integers c_{1},c_{2},...,c_{n} (1\leq c_{i}\leq 1e6).

Output

    Print "Yes" (without quotes) if Arya has a winning strategy independent of value of x, or "No" (without quotes) otherwise.

Examples

Input

4 5
2 3 5 12

Output

Yes

Input

2 7
2 3

Output

No

Note

    In the first sample, Arya can understand x mod 5 because 5 is one of the ancient numbers.

    In the second sample, Arya can't be sure what x mod 7 is. For example 1 and 7 have the same remainders after dividing by 2 and 3, but they differ in remainders after dividing by 7.

 

 

 

 

發佈了28 篇原創文章 · 獲贊 47 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章