[硫化铂]LJJ的电阻⽹格

LJJ的电阻⽹格

题目概述

在这里插入图片描述
在这里插入图片描述

题解

什么**出题人,在这里出物理题,你当人人都是物竞的是吧。

首先,我们可以一个一个点地来想,不过我们首先可以将所有的点分成两大类 x = y x=y x=y x ≠ y x\not = y x=y两大类。
对于 x = y x=y x=y的部分,观察到所有的 x , y x,y x,y范围都是远大于 x ≠ y x\not = y x=y部分的,而它又给了我们一个公式,显然是要让我们通过这个公式算它的答案。
对于 x = 100000 , y = 100000 x=100000,y=100000 x=100000,y=100000的点,显然可以按它的公式,算出 ∑ i = 1 x 1 2 i − 1 \sum_{i=1}^x\frac{1}{2i-1} i=1x2i11,再乘上 2 π \frac{2}{\pi} π2就行了。
x , y ∈ [ 1 0 10 , 1 0 15 ] x,y\in[10^{10},10^{15}] x,y[1010,1015]的部分显然是让我们通过更快的方式去计算这个值。
lim ⁡ x → + ∞ ∑ i = 1 x 1 2 i − 1 = lim ⁡ x → + ∞ ∑ i = 1 2 x 1 i − 1 2 lim ⁡ x → + ∞ ∑ i = 1 x 1 i \lim_{x\rightarrow +\infty}\sum_{i=1}^x\frac{1}{2i-1}=\lim_{x\rightarrow +\infty}\sum_{i=1}^{2x}\frac{1}{i}-\frac{1}{2}\lim_{x\rightarrow +\infty}\sum_{i=1}^x\frac{1}{i} x+limi=1x2i11=x+limi=12xi121x+limi=1xi1
而我们又知道 lim ⁡ x → ∞ ∑ i = 1 x 1 i \lim_{x\rightarrow \infty}\sum_{i=1}^{x}\frac{1}{i} limxi=1xi1是与 ln ⁡ n \ln n lnn比较接近的,由莱昂哈德·欧拉告诉我们它们的差值是趋近于 γ = 0.577215664901532860606512090082402431042159335...... \gamma=0.577215664901532860606512090082402431042159335...... γ=0.577215664901532860606512090082402431042159335......,于是我们的答案就是 ln ⁡ ( 2 x ) − 1 2 ln ⁡ ( x ) + γ 2 \ln(2x)-\frac{1}{2}\ln (x)+\frac{\gamma}{2} ln(2x)21ln(x)+2γ

而对于 x ≠ y x\not = y x=y的部分,我们观察到 x , y x,y x,y都相当的小的,我们可以用稍微暴力的方法求解。
对于 x = 1 , y = 0 x=1,y=0 x=1,y=0的部分,学过高中物理的人应该比较容易算出答案。
我们要计算的是 ( 0 , 0 ) − > ( 0 , 1 ) (0,0)->(0,1) (0,0)>(0,1)这一条边的等效电阻,可以通过计算该边上的电流计算出。
该电流,我们可以通过施加电场构造出来。
施加第一个电场,使得有 I I I的电流从点 a a a进入,向无限蔓延出去,显然,这样的话我们的电场应该达到如下的效果,
在这里插入图片描述
显然,通过对称性,点 a a a向四个方向中每个方向流去的电流都应该是 I 4 \frac{I}{4} 4I,施加在 a − > b a->b a>b的边上的电流应该是 I 4 \frac{I}{4} 4I
我们再在点 b b b上施加一个类似但反向的电场,使得电流从四面八方涌来,从 b b b流出一个 I I I的电流,根据电场的可叠加性,这样的话,整张图就不会有电荷的堆积,而是形成了一个大小为 I I I的回路。
同样,这个电场也会在 a − > b a->b a>b的边上有 I 4 \frac{I}{4} 4I的电流。这条边总的电流就是 I 2 \frac{I}{2} 2I,那么我们总电动势为 U I 2 \frac{UI}{2} 2UI,等效电阻为 R 2 \frac{R}{2} 2R

我们记 I ( x , y ) I(x,y) I(x,y)表示从 ( 0 , 0 ) (0,0) (0,0)到点 ( x , y ) (x,y) (x,y)的电流大小,我们已经轻易地求出了 I ( 1 , 0 ) I(1,0) I(1,0) I ( x , x ) I(x,x) I(x,x),我们要尝试通过这些算出我们剩下的 I ( x , y ) I(x,y) I(x,y)
显然,从一个点流入的电流与从其流出的电流应该大小是相同的,否则它就要累积电荷了。
而根据对称性,每个点向四周流去的电流应该是相同的,那么我们就有 4 I ( x , y ) = I ( x − 1 , y ) + I ( x , y − 1 ) + I ( x + 1 , y ) + I ( x , y + 1 ) 4I(x,y)=I(x-1,y)+I(x,y-1)+I(x+1,y)+I(x,y+1) 4I(x,y)=I(x1,y)+I(x,y1)+I(x+1,y)+I(x,y+1)成立。
我们可以通过我们的已有信息算出未知信息。
在这里插入图片描述
我们可以不断枚举 x + y = k x+y=k x+y=k上的点,一层一层下去,按照向量的方向构造出下一层的向量。
根据上面的式子,在我们已知 I ( x , y ) , I ( x − 1 , y ) , I ( x , y − 1 ) I(x,y),I(x-1,y),I(x,y-1) I(x,y),I(x1,y),I(x,y1)时,再知道 I ( x + 1 , y ) I(x+1,y) I(x+1,y) I ( x , y + 1 ) I(x,y+1) I(x,y+1)中的一者就可以知道另一者。
对于中间 y = x y=x y=x上的点,其两侧的 I ( x + 1 , y ) I(x+1,y) I(x+1,y) I ( x , y + 1 ) I(x,y+1) I(x,y+1)显然是等效的,所以我们只需要知道前三者就行。 I ( x , y ) I(x,y) I(x,y)我们已预先知道, I ( x − 1 , y ) I(x-1,y) I(x1,y) I ( x , y − 1 ) I(x,y-1) I(x,y1)也已在上一层得到,我们显然可以轻松的知道 I ( x + 1 , y ) I(x+1,y) I(x+1,y) I ( x , y + 1 ) I(x,y+1) I(x,y+1)
而往该中线的外侧扩张时,对于下一个点,我们也已经构造出两者中的一者,自然也能得到另一个。
到了坐标轴上,我们可以将坐标轴这边的翻转过去得到另一侧的值,自然可以构造出顶上的点。
按这个顺序就可以得到我们的 I ( x , y ) I(x,y) I(x,y)了。
于是乎,我们就轻松地解决该问题了。

时间复杂度 O ( [ x ≠ y ] max ⁡ ( x , y ) 2 ) O([x\not =y]\max(x,y)^2) O([x=y]max(x,y)2)
不过按题解说法, x , y x,y x,y大了就不精确了,所以只开到了 15 15 15

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 80005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL; 
typedef long double ld;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const int mo=998244353;
const int mod=1e5+3;
const int inv2=499122177;
const int jzm=2333;
const int zero=2000;
const int n1=2000;
const int orG=3,ivG=332748118;
const long double Pi=acos(-1.0);
const double eps=1e-12;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1)t=1ll*t*a%p;a=1ll*a*a%p;s>>=1;}return t;}
LL x,y;double ans,dp[50][50];
signed main(){
	freopen("grid.in","r",stdin);
	freopen("grid.out","w",stdout);
	read(x);read(y);
	if(x==1&&y==0){puts("0.500000");return 0;}
	if(x==y){
		if(x<=100000)for(int i=1;i<=x;i++)ans+=1.0/(i+i-1);
		else ans=log(2.0*x)-0.5*(log(1.0*x)-0.57721566490153286060);
		ans*=2.0/Pi;
		printf("%.6f\n",ans);
		return 0;
	}
	dp[0][0]=0;dp[1][0]=dp[0][1]=0.5;
	for(int i=1;i<=max(x,y);i++)dp[i][i]=dp[i-1][i-1]+2.0/Pi/(i+i-1);
	for(int k=1;k<=x+y;k++)
		for(int ix=k/2,iy=(k+1)/2,jx=(k+1)/2,jy=k/2;ix>=0&&jy>=0;ix--,iy++,jx++,jy--){
			if(ix==iy)dp[ix+1][iy]=dp[ix][iy+1]=2.0*dp[ix][iy]-dp[ix-1][iy];
			else if(ix)dp[ix][iy+1]=4.0*dp[ix][iy]-dp[ix-1][iy]-dp[ix][iy-1]-dp[ix+1][iy];
			else dp[ix][iy+1]=4.0*dp[ix][iy]-dp[ix][iy-1]-2.0*dp[ix+1][iy];
			if(jx==jy)dp[jx+1][jy]=dp[jx][jy+1]=2.0*dp[jx][jy]-dp[jx-1][jy];
			else if(jy)dp[jx+1][jy]=4.0*dp[jx][jy]-dp[jx-1][jy]-dp[jx][jy-1]-dp[jx][jy+1];
			else dp[jx+1][jy]=4.0*dp[jx][jy]-dp[jx-1][jy]-2.0*dp[jx][jy+1];
		}
	printf("%.6f\n",dp[x][y]);
	return 0;
}

谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值