1. 程式人生 > 程式設計 >React國際化react-i18next詳解

React國際化react-i18next詳解

構造題其實可以調整做。

前言

緩慢填坑ing

差分約束的題還是見少了,完全沒思路。

Acetyl orz

題目

洛谷

講解

首先我們不考慮 \(10^6\) 這個限制,顯然做法很多,比如強制 \(a_{n,i}=a_{j,m}=0\),然後遞推一下就好了。

然後調整解決問題。

可以發現一行如果 \(+r\ -r\ +r\ -r,...\),並不會對 \(b\) 矩陣產生影響,同理,一列也沒有影響,於是我們可以構造出這麼一個矩陣表示調整值:

\[\begin{pmatrix}&r_1+c_1\ &-r_1+c_2\ &r_1+c_3,&\cdots\\&r_2-c_1\ &-r_2-c_2\ &r_2-c_3,&\cdots\\&r_3+c_1\ &-r_3+c_2\ &r_3+c_3,&\cdots\\&\vdots&\vdots&\vdots&\ddots\\\end{pmatrix} \]

但這個矩陣的形式並不好看,我們微調一下:

\[\begin{pmatrix}&r_1-c_1\ &c_2-r_1\ &r_1-c_3,&\cdots\\&c_1-r_2\ &r_2-c_2\ &c_3-r_2,&\cdots\\&r_3-c_1\ &c_2-r_3\ &r_3-c_3,&\cdots\\&\vdots&\vdots&\vdots&\ddots\\\end{pmatrix} \]

這樣看上去就統一多了,然後直接套差分約束即可。

具體的,上述矩陣為 \(\Delta_{i,j}=X-Y\) 的形式,可以得到不等式 \(0\le a_{i,j}+\Delta_{i,j}\le 10^6\)

,再轉換一下變成 \(-a_{i,j}\le \Delta_{i,j}\le 10^6-a_{i,j}\),連邊即可。

值得注意的是如果使用裸的SPFA判負環會TLE,你可使用上文提到的巨佬的deque優化寫法,也可以使用洛谷上評測更快的stack寫法。個人經驗是如果用SPFA判負環,stack會快很多。

雖然感覺時間複雜度很離譜,但是可以通過。

程式碼

程式碼不長,容易理解
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;

typedef long long LL;
const int MAXN = 305;
const LL INF = 1ll << 60;
int n,m;
int a[MAXN][MAXN],b[MAXN][MAXN];
bool inq[MAXN<<1];
LL dis[MAXN<<1];

LL Read()
{
	LL x = 0,f = 1; char c = getchar();
	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int head[MAXN<<1],tot,cnt[MAXN<<1];
struct edge
{
	int v,w,nxt;
}e[MAXN*MAXN*4];
void Add_Edge(int x,int y,int z)
{
	e[++tot] = edge{y,z,head[x]};
	head[x] = tot;
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	for(int T = Read(); T ;-- T)
	{
		n = Read(); m = Read();
		for(int i = 1;i < n;++ i)
			for(int j = 1;j < m;++ j)	
				b[i][j] = Read();
		for(int i = 1;i <= m;++ i) a[n][i] = 0;
		for(int i = 1;i <= n;++ i) a[i][m] = 0;
		for(int i = n-1;i >= 1;-- i)
			for(int j = m-1;j >= 1;-- j)
				a[i][j] = b[i][j] - a[i+1][j] - a[i][j+1] - a[i+1][j+1];
		for(int i = 1;i <= n+m;++ i) head[i] = cnt[i] = 0,inq[i] = 0,dis[i] = INF; tot = 0;
		for(int i = 1;i <= n;++ i)
			for(int j = 1;j <= m;++ j)
			{
				int MIN = -a[i][j],MAX = 1000000-a[i][j];
				if((i+j)&1) //c-r
				{
					Add_Edge(n+j,i,-MIN);
					Add_Edge(i,n+j,MAX);
				}
				else //r-c
				{
					Add_Edge(i,n+j,-MIN);
					Add_Edge(n+j,i,MAX);
				}
			}
		stack<int> q; q.push(1); dis[1] = 0;
		bool nonono = 0;
		while(!q.empty())
		{
			int x = q.top(); q.pop(); inq[x] = 0;
			for(int i = head[x],v; i && !nonono ;i = e[i].nxt)
			{
				v = e[i].v;
				if(dis[x]+e[i].w < dis[v])
				{
					dis[v] = dis[x] + e[i].w;
					if(!inq[v]) 
					{
						q.push(v);
						++cnt[v];
						if(cnt[v] > n+m) nonono = 1;
						inq[v] = 1;
					}
				}
			}
		}
		if(nonono) {printf("NO\n");continue;}
		printf("YES\n");
		for(int i = 1;i <= n;++ i,putchar('\n'))
			for(int j = 1;j <= m;++ j)
			{
				if((i+j)&1) //c-r
					Put(a[i][j]+dis[n+j]-dis[i],' ');
				else 
					Put(a[i][j]+dis[i]-dis[n+j],' ');
			}
	}
	return 0;
}