#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>

#define PixelEnabled // 支持像素操作前先在编译选项加上 -lgdi32 
using namespace std;

struct RandomGenerator {
	int StartSeed;
	int CurSeed;
	int CurCount;
	RandomGenerator() {
		CurCount = 0;
		CurSeed = time(0);
		StartSeed = CurSeed;
		srand(CurSeed);
	}
	RandomGenerator(int Seed) {
		CurCount = 0;
		CurSeed = Seed;
		StartSeed = CurSeed;
		srand(CurSeed);
	}
	void Srand(int Seed) {
		CurCount = 0;
		CurSeed = Seed;
		StartSeed = CurSeed;
		srand(CurSeed);
	}
	int Rand() {
		++CurCount;
		if (CurCount==0x8000) {
			CurCount = 0;
			CurSeed += (StartSeed^0x66CCFF)+1;
			srand(CurSeed);
		}
		return rand();
	}
	int Rand32() {
		return ((Rand()>>1)<<16)|Rand()|((Rand()&1)<<15);
	}
	int Rand(int Mod) {
		return Rand32()%Mod;
	}
} Rnd;
struct CuSO4 {
	HDC Hdc;
	HANDLE Hout;
	int FQ[7] = {523,578,659,698,784,880,990};
	double DeltaX, DeltaY;
	double Rat;
	CuSO4(bool k) {
		if (!k) return;
		Hdc = GetDC(GetConsoleWindow());
		Hout = GetStdHandle(STD_OUTPUT_HANDLE);
		DWORD dwMode = 0;
		DeltaX = DeltaY = 0.0;
		Rat = 1.0;
		GetConsoleMode(Hout, &dwMode);
		SetConsoleMode(Hout, dwMode|4);
		#ifdef PixelEnabled
			for (int i=0; i<100; ++i) {
				for (int j=0; j<100; ++j) {
					SetPixel(Hdc, i, j, 0);
				}
			}
		#endif
	}
	void Beep(int X, int Ud, double Tm) { // 发出 X^{+Ud} 音调 Tm 秒 
		int T = int(round(Tm*500.0));
		if ((X<1)||(X>7)) {
			Sleep(T); return;
		}
		int F = FQ[X-1];
		if (Ud>=0) F=(F<<Ud);
		else F=(F>>(-Ud));
		::Beep(F, T);
	}
	void Curpos(int x, int y) { // 光标移到 (x, y) 
		SetConsoleCursorPosition(Hout, {y,x});
	}
	int CursorX() {
		POINT cp;
		GetCursorPos(&cp);
		return int(round(double(cp.y)*Rat+DeltaX));
	}
	int CursorY() {
		POINT cp;
		GetCursorPos(&cp);
		return int(round(double(cp.x)*Rat+DeltaY));
	}
	void SystemColor(int x) { // 使用系统默认文本颜色 
		SetConsoleTextAttribute(Hout, x);
	}
	void Color(int R, int G, int B) { // 使用自定义文本颜色 (RGB) 
		wprintf(L"\x1b[38;2;%d;%d;%dm", R, G, B);
	}
	void Color(int x) { // 使用自定义文本颜色 (十六进制代码)
		int R = (x>>16);
		int G = ((x>>8)&((1<<8)-1));
		int B = (x&((1<<8)-1));
		Color(R, G, B);
	}
  
	void ResetCursor() { // 校准鼠标位置 
		system("cls");
		SystemColor(7); Curpos(0,0);
		printf("校准即将开始,请把窗口调整到合适大小、位置,然后按任意键继续...");
		getch();
		system("cls"); Curpos(0,0);
		printf("请把鼠标移到红色标记中央,然后按下 [A] 键校准");
		for (int i=195; i<=205; ++i) {
			for (int j=195; j<=205; ++j) Plot(i,j,0xEE0000);
		}
		char ch = getch();
		while ((ch!='A')&&(ch!='a')) ch=getch();
		POINT cp;
		GetCursorPos(&cp);
		int A=cp.y, B=cp.x;
		system("cls"); Curpos(0,0);
		printf("请把鼠标移到红色标记中央,然后按下 [B] 键校准");
		for (int i=395; i<=405; ++i) {
			for (int j=395; j<=405; ++j) Plot(i,j,0xEE0000);
		}
		ch = getch();
		while ((ch!='B')&&(ch!='b')) ch=getch();
		GetCursorPos(&cp);
		int C=cp.y, D=cp.x;
		Rat = 200.0/double(D-B);
		DeltaX = 200.0-Rat*double(A);
		DeltaY = 200.0-Rat*double(B);
		system("cls");
		printf("校准完毕,请勿再移动窗口。按任意键继续...");
		getch();
		system("cls");
	}
	#ifdef PixelEnabled
		void Plot(int x, int y, int R, int G, int B) { // 在 (x,y) 像素绘制颜色 (RGB) 
			SetPixel(Hdc, y+30, x+30, R+(G<<8)+(B<<16));
		}
		int Get(int x, int y) { // 查询 (x,y) 像素处的颜色 (十六进制代码)
			int tmp = GetPixel(Hdc, y+30, x+30);
			int R = (tmp&((1<<8)-1));
			int G = ((tmp>>8)&((1<<8)-1));
			int B = (tmp>>16);
			return (R<<16)+(G<<8)+B;
		}
		void Plot(int x, int y, int clr) { // 在 (x,y) 像素绘制颜色 (十六进制代码)
			Plot(x, y, (clr>>16), ((clr>>8)&((1<<8)-1)), (clr&((1<<8)-1)));
		}
	#endif
	int Mix(int ca, int cb, double rt) { // 颜色 ca 和 cb 按 rat 比例混合 (十六进制代码)
		int Ar = (ca>>16);
		int Ag = ((ca>>8)&((1<<8)-1));
		int Ab = (ca&((1<<8)-1));
		int Br = (cb>>16);
		int Bg = ((cb>>8)&((1<<8)-1));
		int Bb = (cb&((1<<8)-1));
		int R = int(floor(rt*double(Ar)+(1.0-rt)*double(Br)));
		int G = int(floor(rt*double(Ag)+(1.0-rt)*double(Bg)));
		int B = int(floor(rt*double(Ab)+(1.0-rt)*double(Bb)));
		return (max(0,min(255,R))<<16)+(max(0,min(255,G))<<8)+max(0,min(255,B));
	}
} Sc(1);

double a[2010][2010];
vector<pair<int,int> > v;
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
int n;

int bel(double x) {
	return int(floor(x*5.0));
}
int bel2(double x) {
	return int(floor(x*15.0));
}
double lower_lim = 0.05;
double upper_lim = 0.5;
bool lower(double x) {
	return x<lower_lim;
}
bool fff = true;
void ep(int i, int j) {
	if (!fff) return;
	int clr;
	if (a[i][j]<=upper_lim) clr=Sc.Mix(0xAAFF80,0x35601D,a[i][j]/upper_lim);
	else clr=Sc.Mix(0xFFFFFF,0xAAFF80,(a[i][j]-upper_lim)/(2.1-upper_lim));
	Sc.Plot(i, j, clr);
}
void smooth(int cnt) {
	int sz=n*n, m=cnt*sz;
	int cc = 0;
	while (m--) {
		int x=cc/n+1, y=cc%n+1;
		++cc; if (cc>=sz) cc-=sz;
		int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
		if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
		double p=a[x][y], q=a[nx][ny];
		a[x][y]=(p+p+q)/3.0; a[nx][ny]=(p+q+q)/3.0;
		ep(x,y); ep(nx,ny);
	}
}
void asmooth(int cnt) {
	int sz=n*n, m=cnt*sz;
	int cc = 0;
	while (m--) {
		int x=cc/n+1, y=cc%n+1;
		++cc; if (cc>=sz) cc-=sz;
		int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
		if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
		double p=a[x][y], q=a[nx][ny];
		a[x][y]=q; a[nx][ny]=p;
		ep(x,y); ep(nx,ny);
	}
}
int main() {
	fff = false;
	if (fff) getch();
	Rnd.Srand(1);
	n = 1300;
	for (int i=1; i<=n; ++i) {
		for (int j=1; j<=n; ++j) {
			v.push_back(make_pair(i,j)); a[i][j]=-1;
		}
	}
	int sz = n*n;
	for (int i=0; i<sz; ++i) swap(v[i],v[Rnd.Rand(sz)]);
	for (int i=0; i<sz; ++i) {
		int x=v[i].first, y=v[i].second;
		if (a[x][y]>=-0.5) continue;
		int bbc = 100000; 
		double val = Rnd.Rand(1025)/1024.0;
		int num = Rnd.Rand(bbc);
		while (num--) {
			int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
			if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
			a[x][y]=val; x=nx; y=ny;
		}
	}
	for (int i=1; i<=n; ++i) {
		for (int j=1; j<=n; ++j) ep(i,j);
	}
	asmooth(20000000/sz);
	for (int i=1; i<=n; ++i) {
		for (int j=1; j<=n; ++j) {
			int dis = int(sqrt(i*i+j*j));
			double rat = 1.0-double(dis)/sqrt(n*n)*1.1;
			rat = 2.0*max(0.0275,rat);
			a[i][j] = a[i][j]*rat+rat*0.1;
			ep(i, j);
		}
	}
	for (int i=0; i<sz; ++i) swap(v[i],v[Rnd.Rand(sz)]);
	for (int i=0; i<sz/15000; ++i) {
		int x=v[i].first, y=v[i].second;
		int bbc = 10000; 
		double val=Rnd.Rand(1025)/1024.0; val*=val;
		val *= min(2.0,a[x][y]+0.3);
		int num = Rnd.Rand(bbc);
		while (num--) {
			int d=Rnd.Rand(4), nx=x+dx[d], ny=y+dy[d];
			if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
			a[x][y]=val; x=nx; y=ny;
			ep(x, y);
		}
	}
	smooth(10000000/sz);
	getch();
	for (;;) {
		for (int s=0; s<sz; ++s) {
			int i=v[s].first, j=v[s].second;
			bool flag=false, flag2=false, bord=false;
			for (int d=0; d<4; ++d) {
				int nx=i+dx[d], ny=j+dy[d];
				if ((min(nx,ny)<0)||(max(nx,ny)>n)) continue;
				if (bel(a[i][j])>bel(a[nx][ny])) flag=true;
				if (bel2(a[i][j])>bel2(a[nx][ny])) flag2=true;
				if (lower(a[i][j])<lower(a[nx][ny])) bord=true;
			}
			if (bord) Sc.Plot(i,j,0x0775BF);
			else if (lower(a[i][j])) {
				Sc.Plot(i, j, Sc.Mix(0x49B6FF,0x0775BF,a[i][j]/lower_lim));
			}
			else {
				int clr;
				if (a[i][j]<=upper_lim) clr=Sc.Mix(0xAAFF80,0x35601D,a[i][j]/upper_lim);
				else clr=Sc.Mix(0xFFFFFF,0xAAFF80,(a[i][j]-upper_lim)/(2.1-upper_lim));
				if (flag) clr=Sc.Mix(0x000000,clr,0.5);
				else if (flag2) clr=Sc.Mix(0x000000,clr,0.2);
				Sc.Plot(i, j, clr);
			}
		}
	}
	return 0;
}