普通视图

发现新文章,点击刷新页面。
昨天以前Rei's Blog

XiaomiEU 固件添加国行 NFC

2025年12月12日 20:50

近期将手机从 AfterlifeOS 这一类原生刷回了 HyperOS3, 小米14 的类原生还是不够完善

不过国行版本的 HyperOS 不超过三天就让我想把手机摔了, 因此刷了基于国行固件的魔改版本 XIAOMI.EU

但是刷完之后, 国行的 NFC 功能用不了, 我的车钥匙/门卡/交通卡可还依赖这玩意呢

找了一下还没有适配当前版本的 Kernel SU 模块, 于是自己解包做了一个

解包国行系统包

先下载国行包并解压

1
2
wget https://bkt-sgp-miui-ota-update-alisgp.oss-ap-southeast-1.aliyuncs.com/OS3.0.5.0.WNCCNXM/houji-ota_full-OS3.0.5.0.WNCCNXM-user-16.0-306ce971bf.zip
unzip houji-ota_full-OS3.0.5.0.WNCCNXM-user-16.0-306ce971bf.zip payload.bin

现在的安卓刷机包大多会打成 payload.bin 这种包格式, 需要先解包

1
2
3
4
wget https://github.com/ssut/payload-dumper-go/releases/download/1.3.0/payload-dumper-go_1.3.0_linux_amd64.tar.gz
tar -xvf payload-dumper-go_1.3.0_linux_amd64.tar.gz
chmod +x payload-dumper-go
./payload-dumper-go -o ./ ./payload.bin

查看文件尺寸, 最大的是这个 product.imgfile 指令查看后可以知道这是个 erofs 的单分区镜像包, 我们将其挂载

1
2
3
pacman -S erofs-utils erofsfuse
mkdir product
mount -t erofs -o loop product.img product

然后在挂载镜像的 app 目录下找到 MINextpay MITSMClient UPTsmService 三个必要组件, 将其打包成一个最简的 KernelSU module 刷入即可, 也就是只有 system/app/组件module.prop 文件的最简包

1
2
3
4
cp -a ./product/app/MINextpay ./module/system/app/MINextpay
cp -a ./product/app/MITSMClient ./module/system/app/MITSMClient
cp -a ./product/app/UPTsmService ./module/system/app/UPTsmService
cp -a ./product/app/MIUISuperMarket ./module/system/app/MIUISuperMarket

为了方便后续更新版本, 做了个 Github Action 用来打包

其中奇怪的一点是, 在 Action 中使用 mount -t erofs -o loop product.img product 挂载镜像后 拷贝之后, 执行到 cp 这一步的时候会报

挂载

Github Action 报错

看上去是内存超限了的样子

因此换成了 fsck.erofs product.img --extract=product 指令将镜像中的文件提取出来

最后成品可以在 https://github.com/ReiAccept/MiPay4XiaomiEU 中找到

ICPC 2020 Shenyang

2021年9月6日 20:35
Featured image of post ICPC 2020 Shenyang

CF Gym : Dashboard - The 2020 ICPC Asia Shenyang Regional Programming Contest - Codeforces

D Journey to Un’Goro

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<bits/stdc++.h>
//#include<bits/extc++.h>
//#define int long long//__int128
#define mmst0(x) memset(x,0,sizeof(x))
#define mmst3f(x) memset(x,0x3f,sizeof(x))
#define pb(x) emplace_back(x)
#define mkp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
//using namespace __gnu_pbds; //If using pbds don't using std!
typedef long long ll;
typedef long double rld;
typedef unsigned long long ull;

const rld eps = 1e-6;
const int INF=0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;//LLINF
const int MAXN=(int)3e5+3;

inline char nc(){static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
inline int read(){int s=0,w=1;char ch=nc();while(!isdigit(ch)){if(ch=='-')w=-1;ch=nc();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=nc();} return s*w;}
//inline void read(int &x){char ch=nc();x=0;while (!(ch>='0'&&ch<='9')) ch=nc();while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=nc();}//根据参数个数自动选择
//void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

int n,cnt;
char s[MAXN];

void dfs(int now, int ji, int ou, bool flag)
{
    if(cnt==100) exit(0);
    if(n%2)
    {
        if(ji+(n-ji-ou) < (n>>1) || ou + (n-ji-ou) < (n>>1) || ji > (n>>1)+1 || ou > (n>>1)+1) return;
    }
    else
    {
        if(ji+(n-ji-ou) < (n>>1) || ou + (n-ji-ou) < (n>>1) || ji > (n>>1) || ou > (n>>1)) return;
    }
    if(now == n)
    {
        for(int i=1;i<=n-1;i++) printf("%c",s[i]);
        printf("\n");
        cnt++;
        return;
    }
    s[now]='b';
    if(flag) dfs(now+1,ji+1,ou,flag);
    else dfs(now+1,ji,ou+1,flag);
    s[now]='r'; //flag取反
    if(!flag) dfs(now+1,ji+1,ou,!flag);
    else dfs(now+1,ji,ou+1,!flag);
}

inline void work()
{
    n=read()+1; ll ans=((ll)n/2) * ((ll)n-(ll)n/2);
    printf("%lld\n",ans);
    dfs(1,0,1,false);
    return;
}

signed main()
{
    //ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=1;//(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed Case=1; Case<=T; Case++)
    {
        //printf("Case %d: ",Case);
        //while(cin>>n) work(n);
        work();
    }
    return 0;
}
//构造一个长度为 n 的只含有 b,r 的字符串,使得子串中 r 数量为奇数的最多
//r 看成 1,b 看成 0 的话,前缀和中为奇数的子串就满足要求

F Kobolds and Catacombs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<bits/stdc++.h>
//#include<bits/extc++.h>
//#define int long long//__int128
#define mmst0(x) memset(x,0,sizeof(x))
#define mmst3f(x) memset(x,0x3f,sizeof(x))
#define pb(x) emplace_back(x)
#define mkp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
//using namespace __gnu_pbds; //If using pbds don't using std!
typedef long long ll;
typedef long double rld;
typedef unsigned long long ull;

const rld eps = 1e-6;
const int INF=0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;//LLINF
const int MAXN=(int)1e6+3;

inline char nc(){static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
inline int read(){int s=0,w=1;char ch=nc();while(!isdigit(ch)){if(ch=='-')w=-1;ch=nc();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=nc();} return s*w;}
//inline void read(int &x){char ch=nc();x=0;while (!(ch>='0'&&ch<='9')) ch=nc();while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=nc();}//根据参数个数自动选择
//void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

int n;
int a[MAXN],b[MAXN];

inline void work()
{
    n=read();
    for(int i=1;i<=n;i++) b[i]=a[i]=read();
    sort(b+1,b+1+n,[](int x,int y){return y>x;});
    //for(int i=1;i<=n;i++) printf("%d ",b[i]);
    int cura=0,curb=0,ans=0;
    for(int i=n;i>=1;i--)
    {
        cura+=a[i]; curb+=b[i];
        if(cura==curb) ans++;
    }
    printf("%d\n",ans);
    return;
}

signed main()
{
    //ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=1;//(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed Case=1; Case<=T; Case++)
    {
        //printf("Case %d: ",Case);
        //while(cin>>n) work(n);
        work();
    }
    return 0;
}

G The Witchwood

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<bits/stdc++.h>
//#include<bits/extc++.h>
#define int long long//__int128
#define mmst0(x) memset(x,0,sizeof(x))
#define mmst3f(x) memset(x,0x3f,sizeof(x))
#define pb(x) emplace_back(x)
#define mkp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
//using namespace __gnu_pbds; //If using pbds don't using std!
typedef long long ll;
typedef long double rld;
typedef unsigned long long ull;

const rld eps = 1e-6;
const int INF=0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;//LLINF
const int MAXN=(int)1e3+3;

inline char nc(){static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
inline int read(){int s=0,w=1;char ch=nc();while(!isdigit(ch)){if(ch=='-')w=-1;ch=nc();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=nc();} return s*w;}
//inline void read(int &x){char ch=nc();x=0;while (!(ch>='0'&&ch<='9')) ch=nc();while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=nc();}//根据参数个数自动选择
//void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

int n,k;
int a[MAXN];

inline void work()
{
    n=read(); k=read();
    for(int i=1;i<=n;i++) a[i]=read();
    sort(a+1,a+1+n,[](int x,int y){return y<x;});
    int ans=0;
    for(int i=1;i<=k;i++) ans+=a[i];
    printf("%lld\n",ans);
    return;
}

signed main()
{
    //ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=1;//(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed Case=1; Case<=T; Case++)
    {
        //printf("Case %d: ",Case);
        //while(cin>>n) work(n);
        work();
    }
    return 0;
}

I Rise of Shadows

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<bits/stdc++.h>
//#include<bits/extc++.h>
#define int long long//__int128
#define mmst0(x) memset(x,0,sizeof(x))
#define mmst3f(x) memset(x,0x3f,sizeof(x))
#define pb(x) emplace_back(x)
#define mkp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
//using namespace __gnu_pbds; //If using pbds don't using std!
typedef long long ll;
typedef long double rld;
typedef unsigned long long ull;

const rld eps = 1e-6;
const int INF=0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;//LLINF
const int MAXN=(int)1e5+3;

inline char nc(){static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
inline int read(){int s=0,w=1;char ch=nc();while(!isdigit(ch)){if(ch=='-')w=-1;ch=nc();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=nc();} return s*w;}
//inline void read(int &x){char ch=nc();x=0;while (!(ch>='0'&&ch<='9')) ch=nc();while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=nc();}//根据参数个数自动选择
//void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

int h,m,a;

inline void work()
{
    h=read();m=read();a=read();
    if(a == h*m/2) printf("%lld\n",h*m);
    else
    {
        int g=__gcd(h-1,m);
        printf("%lld\n",g*(((a/g)<<1)|1));
    }
    return;
}

signed main()
{
    //ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=1;//(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed Case=1; Case<=T; Case++)
    {
        //printf("Case %d: ",Case);
        //while(cin>>n) work(n);
        work();
    }
    return 0;
}

K Scholomance Academy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include<bits/stdc++.h>
#define int long long//__int128
#define mmst0(x) memset(x,0,sizeof(x))
#define mmst3f(x) memset(x,0x3f,sizeof(x))
#define pb(x) emplace_back(x)
#define mkp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef long double rld;
typedef unsigned long long ull;

const rld eps = 1e-6;
const int INF=0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;//LLINF
const int MAXN=(int)1e6+3;

//int read(){int s=0,w=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();} return s*w;}
//void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

struct Node
{
    bool c;
    int s;
}a[MAXN];

int n,tpfn,tnfp;

void work()
{
    //scanf("%d",&n);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        char c; //scanf("%c %d",c,&a[i].s);
        cin>>c>>a[i].s;
        a[i].c=(c=='+');
        //printf("111");
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i].c) tpfn++;
        else tnfp++;
    }
    sort(a+1,a+1+n,[](Node a,Node b){
        if(a.s == b.s){
            if(b.c) return false;
            if(a.c) return true;
        }
        return a.s<b.s;
    });
    int tp=tpfn,fp=0,cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i].c) tp--;
        else cnt+=tp;
    }
    rld ans=(rld)cnt / (tpfn*tnfp);
    printf("%.9LF\n",ans);
    return;
}

signed main()
{
    //ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=1;//(int)read();
    for(signed Case=1; Case<=T; Case++)
    {
        //printf("Case %d: ",Case);
        //while(cin>>n)
        work();
    }
    return 0;
}

ICPC 2020 Jinan A Matrix Equation

2020年12月31日 20:43

这个题算是个翻车题,做出来可以铁翻银的,燃鹅翻车在这个题上了

证明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<bits/stdc++.h>
//#include<bits/extc++.h>
#define int long long
//#define int __int128
#define ull unsigned long long
#define MMST(x,y) memset(x,y,sizeof(x))

using namespace std;
//using namespace __gnu_pbds;

const int INF=0x3f3f3f3f;
const int MOD=998244353;

int read(){char c;int num,f=1;while(c=(char)getchar(),!isdigit(c))if(c=='-')f=-1;num=(int)(c-'0');while(c=(char)getchar(),isdigit(c))num=num*10+(int)(c-'0');return num*f;}
void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

int n,ans=1;
int a[203][203],b[203][203];
bitset<203> bit[203];

void insert(bitset<203> x)
{
    for(int i=1;i<=n;i++)
        if (x[i]) 
        {
            if(!bit[i].count()) 
            {
                bit[i]=x;
                break;
            }
            x^=bit[i];
        }
}

void work()
{
    cin>>n;
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j];
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>b[i][j];
    for(int t=1;t<=n;t++)
    {
        for(int i=1;i<=n;i++) bit[i]=0;
        for(int i=1;i<=n;i++)
        {
            bitset<203> x=0;
            for(int j=1;j<=n;j++) x[j]=a[i][j];
            x[i]=x[i]^b[i][t];
            insert(x);
        }
        for(int i=1;i<=n;i++)if(!bit[i].count()) ans=(ans<<1)%MOD;
    }
    cout<<ans<<endl;
    return;
}

signed main()
{
    int T=1;//read();
	for(int Case=1;Case<=T;Case++)
    {
        //printf("Case #%d: ",Case);
        work();
    }
    return 0;
}

ICPC 2020 Shangahi

2020年12月13日 20:57

嘛,没想到我的ICPC之旅的第一站就那么卷,开局南师大6S AC最速传说,然后被dq了,开场签到很稳,和文哥直接推出了公式,和黄总写的暴力程序直接对拍正确A掉签到题

然后在开B和M之间纠结,队伍里就我用过git,就看懂了M的题意,然后和黄总一起构树两次DFS写M,文哥没用过git就没看懂git的忽略操作的意思,文哥去开了B,然后M构树挂了三四次浪费了4H,然后文哥来看了M,这次告诉文哥,git的忽略在这题就理解成删除,文哥上手M题,直接30MIN给过了,文哥·工大唯一真神。到这里已经来不及做B了,实际上文哥B的思路是正确的。

感觉这场我有点演==挂件模式全开,我的构树是竞赛少用的指针+vector构树,然后和黄总的构树代码完全不兼容,后来想到了Trie,但是用的模板好像是假的==

B

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<bits/stdc++.h>

using namespace std;

const int maxn = 1e3+3;
int cnt,n,m;
char a[maxn][maxn] ,b[maxn][maxn];
int main()
{
	cin >> n >> m;
	for(int i=0;i<n;i++)scanf("%s",a+i);
	for(int i=0;i<n;i++)scanf("%s",b+i);
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
			if(a[i][j]!=b[i][j]) cnt++;
	if(cnt>n*m/2)
    {
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				if(a[i][j]=='.') a[i][j]='X';
				else a[i][j]='.';
	}
	for(int i=0;i<n;i++) printf("%s\n",a+i);
	return 0;
}

D

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<bits/stdc++.h>

using namespace std;

double n,p1,v1,p2,v2,l,r,mid;

double calc(double n,double p,double v)
{
    return min(n-p+n,p+n)/v;
}

void work()
{
    scanf("%lf%lf%lf%lf%lf",&n,&p1,&v1,&p2,&v2);
    double ans=min(calc(n,p1,v1),calc(n,p2,v2));
    if (p1>p2) swap(p1,p2),swap(v1,v2);
    ans=min(ans,max(p2/v2,(n-p1)/v1));
    l=p1,r=p2;
    for (int i=1; i<=100; i++)
    {
        mid=(l+r)/2.0;
        double ans1=calc(mid,p1,v1),ans2=calc(n-mid,p2-mid,v2);
        ans=min(ans,max(ans1,ans2));
        if (ans1>ans2) r=mid;
        else l=mid;
    }
    printf("%.10lf\n",ans);
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)work();
}

G

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include<bits/stdc++.h>

using namespace std;

#define int long long

const int N = 2e5+100;

signed main()
{
	int n;
	scanf("%lld",&n);
	int ans=(n-(n/3))*(n/3)+(n/3)*(n/3-1)/2;
	cout<<ans<<endl;
	return 0;
}

I

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<bits/stdc++.h>
#define MN 500

using namespace std;

typedef long double ld;
const ld pai = acos(-1);

int n,m;

ld len,ans;
ld f[MN+5];

int main()
{
	scanf("%d%d",&n,&m);
	ld d = pai/m; 
	for(int i=1;i<m;i++)
    {
		if(i*d>2)len+=2;
		else len+=i*d;
	}
	len*=2;
	len+=2;
	for(int i=1;i<=n;i++)
    {
		f[i]=len*i+2*m*(i-1)+1+f[i-1];
		ans += m*(f[i]*2-i*len);
	}
    if(m==1) ans-=(2+2*n)*n/2;
	printf("%.10lf\n",(double)ans);
}

M

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include<bits/stdc++.h>
using namespace std; 
int n,m;
int vis[10100];
int qian[10100];
int z[10100];
int shu[10100];
int vi[10100];
int o[10100];
void init(){
	memset(vis,0,sizeof(vis));
	memset(qian,0,sizeof(qian));
	memset(z,0,sizeof(z));
	memset(shu,0,sizeof(shu));
//	memset(vis,0,sizeof(vis));
	memset(vi,0,sizeof(vi));
	memset(o,0,sizeof(o));
}
struct node{
	int i;
	int x;
};
int main()
{
	int T ;
	cin>>T;
	while(T--){
		cin>>n>>m;
		init();
		map<string ,int > mp;
		int tot=1;
		for(int i=1;i<=n;i++){
			string str;
			cin>>str;
			str=str+"/";
			string s;
			int flag=0;
			string p;
			for(int j=0;j<str.size();j++){
				if(str[j]=='/'&&flag==0){
					flag=1;
					p=s;
					if(mp[s]==0){
						mp[s]=++tot;
						qian[tot]=1;
						z[tot]=1;
					}
				}
				else if(str[j]=='/'&&flag==1){
					if(mp[s]==0){
						mp[s]=++tot;
						qian[tot]=mp[p];
						z[tot]=1;
						shu[mp[p]]++;
					}
					p=s;
				}
				s+=str[j];
			}	
		}
		for(int i=1;i<=m;i++){
			string str;
			cin>>str;
			str=str+"/";
			string s;
			int flag=0;
			string p;
			for(int j=0;j<str.size();j++){
				if(str[j]=='/'&&flag==0){
					flag=1;
					p=s;
					if(mp[s]==0){
						mp[s]=++tot;
						qian[tot]=1;
						z[tot]=0;
					}
				}
				else if(str[j]=='/'&&flag==1){
					if(mp[s]==0){
						mp[s]=++tot;
						qian[tot]=mp[p];
						z[tot]=0;
						shu[mp[p]]++;
					}
					p=s;
				}
				s+=str[j];
			}	
		}
//		for(int i=1;i<=tot;i++){
//			cout<<i<<" ";
//		}
//		cout<<endl;
//		for(int i=1;i<=tot;i++){
//			cout<<qian[i]<<" ";
//		}
//		cout<<endl;
//		for(int i=1;i<=tot;i++){
//			cout<<shu[i]<<" ";
//		}
//		cout<<endl;
		queue<node> p;
		int ans=0;
		for(int i=2;i<=tot;i++){
			if(shu[i]==0){
				if(z[i]==1) {
					ans++;	p.push(node{i,z[i]});
				}
			
			}
		}
//		cout<<p.size()<<endl;
//		cout<<ans<<endl;
		while(!p.empty()){
			node t=p.front();
			p.pop();
			vi[qian[t.i]]++;
//			o[qian[t.i]]+=t.x;
//			cout<<t.i<<" "<<t.x<<endl;
			if(vi[qian[t.i]]==shu[qian[t.i]]&&qian[t.i]!=1){
				ans-=shu[qian[t.i]];
				ans++;
				p.push(node{qian[t.i],0});
			}
		}
		cout<<ans<<endl;
	}
}

银欣 CS382

2025年4月6日 05:36
Featured image of post 银欣 CS382

为什么要更换机箱

INWIN 的 MS04 作为 NAS 机箱在我这服役多年,承载了 凄惨红H61 + i5-3470 和 华擎H97M-ITX/ac + E3-1265Lv3 两代硬件,当我这几天想给他升级 B760I + i3-12100 时,机箱的原装电源终于是吃不太消,来自 1U 电源风扇轴承的声音到达了一个让人难以忍受的程度。

为了拯救这个老机器,我还尝试购买了一下海韵的 350M1U 电源更换上去,当时看中的是海韵的 50% 以下电源负载时风扇停转功能。但是这个电源,在 MS04 这个箱子里的散热有点问题,导致虽然时低负载情况下,依旧会在开启一段时间后积热,然后风扇开始转动,海韵给这个电源配备了恐怖的万转风扇,这个风扇在这种情况下并未全速运行,但是依旧有令人讨厌的声音。

还有一点就是,原机上是 4*14T 的 WD HC530 硬盘,其实也有点不够用

终于,在清明节晚上大半夜,我决定是时候光荣退役这台 MS04,换个新的 8 盘位 NAS 机箱。

机箱选型

考虑过以下几个机箱选型

迎广 MS08

那么大一个箱子,明明不缺空间,用的却是 1U 电源,排除

银欣 DS380

虽然是个8盘位箱子,但是硬件兼容性还是小机器那套,排除,不过体积确实小

宝藏盒 Pro

小作坊的定制产品,我还挺喜欢,用的曙光的金属盘架,不过非常贵,1399,排除

银欣 CS380

发布有些年头了,兼容 ATX 主板,塑料盘架,黄鱼400块,京东700块

银欣 CS382

最终选用了这款,兼容 mATX 主板,塑料盘架,京东899,单纯觉得看着比 CS380 顺眼就买了。

电源

电源没啥好说的,海韵和振华的十年质保系列看哪个便宜买哪个就好了。不过离谱的是,刚好赶上振华打折,750W比650W便宜,那就买个750W好了(不过说到底,这套配置哪怕硬盘插满可能连 200W 都到不了吧)

电源包装

电源开箱

顺带说一下振华的新版电源,之前买HG850的时候,他的模组线有送个布袋,但是现在这个新版750W没了,不过附带的新版模组线,比以前的线软了很多很多,好插多了。

装机

很普通的装机,看我博客的人应该不需要看装机过程,很好装的机箱

B760M 刀锋钛

MSI B760M 刀锋钛 这张主板自带 6SATA,把芯片组自带的 SATA 接口全部引出。并且选择 MSI 的主板有个好处, BIOS 里面就可以直接把 RGB 灯光彻底关闭

值得说的一点就是,硬盘笼上的 SATA/SAS 接口是不兼容右向弯头线材的

SATA线材冲突

以及盘架是类似群晖那种,我并不喜欢,建议直接兼容戴尔的服务器盘架算了,不过相比群晖,给了一个螺丝孔加固

盘架

DELL 的 H730 卡在更新最新的固件之后可以直接在 BIOS 里面更改为 HBA 卡模式, TrueNAS 推荐使用 HBA 卡模式, 由 ZFS 直接控制硬盘, 如果是 OMV 之类或者其他 btrfs 的系统, 这里还是建议打开硬件 RAID

不过说实话之前那台 NAS 虽然用的是 TrueNAS 但是其用了 Intel RAID, 然后在 ZFS 里面直接选择条带模式。

其实用更便宜的 DELL H330 HBA 卡就行了, 用 H730 主要是因为这张卡现在可以设置为, 在非 RAID 模式下也使用 DDR Cache

DELL PERC9 H730

storcli 查看, H730 工作在 HBA 模式下的温度只有 42 度

机箱前面板,我到手才知道,这个箱子不仅有一个标准的光驱位,还有个超薄光驱位

前面板

和MS04的合照

和H5 Flow的合照

UPS

由于我现在住的公寓非常逆天,电费没了之后,不会给任何提示就断电,所以一台 UPS 还是很有必要的,地铁一小时按群友价去收了一台全新的 APC BK650M2-CH

UPS

在 TrueNAS 中选好驱动即可使用

TrueNAS UPS Config

装完后剩余槽位与后续改进

  1. 3.5盘位 1 个, 该盘位为内置盘位,没有背板,用SATA线直接连接
  2. 薄光驱位 1 个, 考虑后续真的放个光驱进去
  3. 厚光驱位 1 个, 考虑后面买个热插拔 2.5 硬盘拓展笼子或者 E1.S 笼子
  4. 2.5英寸盘位 2 个, 来点 U2 大船
  5. 主板,迟早要把这个 ITX 板子卖了换个大板子

附录

配件价格表

类型 名称 数量 来源 总价(CNY)
机箱 银欣 CS382 1 京东 899
电源 振华 LEADEX III GOLD 750W 1 京东 659
机械硬盘 WD HC530 4 上台NAS继承 0
机械硬盘 东芝 MG08 4 淘宝 3356
M2 SSD (Cache) PM981a 1T 1 上台NAS继承 0
M2 SSD (OS) SN750 500G 1 上台NAS继承 0
RAID 卡 DELL H730 1 咸鱼 279
SAS 线 安费诺一分四服务器拆机 2 咸鱼 38.8
主板 MSI B760M 刀锋钛 1 闲鱼 719
CPU i3 12100 1 黄鱼 499
内存 阿斯加特 16G 7000Mhz DDR5 2 上台NAS继承 0
散热器 AXP90x53 1 上台NAS继承 0
网卡 华为 SP310 1 上台NAS继承 0
UPS APC BK650M2-CH 1 杭州本地群友 299
总价 6748.8

MikroTik RB5009

2023年7月30日 10:30
Featured image of post MikroTik RB5009

在 Путин, Владимир Владимирович 搞事之前,RB5009 的价格一直是 12xx 软妹币……

然后……然后……这玩意就成理财产品了……

观望了好几年,这玩意的价格从 12xx -> 2xxx -> 13xx 虽然价格还是很高,但是还算可以接受

不过一个 10G SFP+ 一个 2.5G RJ45,剩下 7 个都是 1000M 口这种配置,MikroTik做出来属实有些膈应人了……

哦,背板带宽还跑不满

不过主要是 E3-1265Lv3 软路由实在是撑不起家里的网络了,不得不换一个

包装盒

顶面

正面

目前杭州租的房子里机架还没搞好,只能丢个袋子里挂起来,灵车的很

等下次回台州把猫棒什么都拿来,淘汰掉联通的垃圾光猫

Tips: 如果您要将 RB5009 与 RTL960x 系列 SFP 猫棒协商 2.5G 速率

首先需要 SSH到猫棒上执行 flash set LAN_SDS_MODE 6 然后回到 winbox,关闭自动协商,设置速率为 2.5G baseX,然后需要等待第一次重协商的时间会比较长,参考资料

方程豹 钛7

2025年12月3日 23:09
Featured image of post 方程豹 钛7

换车与选车

从 2019 年高中毕业拿到驾照到我工作两年,我开的车一直是家里的 Audi A6L 55TFSI Quattro 车型,说实话我相当喜欢这辆车,底盘稳定可靠,动力跟脚,机械结构上除了发动机烧机油外没见过啥问题,让我信心十足的度过了我的新手驾驶期。

不过工作两年后,我需要在杭州买一辆车,需要满足以下条件

  1. 品牌无所谓,家里一直开的是BBA,我自己没啥情怀
  2. 某方面的技术领先(这点其实淘汰了日系,只留下了德系(发动机/底盘技术领先)和国产车(三电技术领先))
  3. 买起来比较简单……别那种换电租电什么方案一堆的
  4. 我自己的现金流支持全款买

算了一下自己可以拿出来的流动资金,最开始的换车计划选了以下三台车(当然我实际上不止试驾了三台)

  • Xiaomi YU7 Pro
  • Tesla Model Y
  • Audi Q6L

一些试驾与感受

Xiaomi YU7 Pro

好开,好车,我各个方面都很喜欢,但是提车要38周,遂放弃

如果不是提车慢,这篇文章就是小米YU7了

Tesla Model Y

好开,底盘稳,动力强,操控灵

但是我不好说这是不是一辆好车

作为一个一直坐家中BBA传统油车长大的人,我认为,车内座舱的体验也是驾车很重要的一部分,特斯拉的内饰真不太行

老生常谈的 屏幕换档 方向盘按键转向灯 也是我觉得难受的地方

Audi E5

不错,但是没有四个圈不好看

Audi Q6L

油改电真不行吧

焕新极氪7X

全车电动门很棒, 车机大屏和很棒, 整车加速, 操控都不错, 还有空气悬挂, 就是后排空间可能有点小

那这车那么好, 为什么不买呢?

家里人听说是吉利车:吉利车,天~窗~漏~水~啦~

哈哈,台州人对吉利的刻板印象来了

不过认真的说,吉利车不差,油的部分比BYD好,我觉得是无可争议的国产第一,底盘调教在国产车中也十分优秀, 但是电的部分确实比不上BYD

方程豹钛7

说起来我最开始不认识这个牌子,但是滨江展厅开在吉利店边上,路过的时候看到里面摆了一辆钛7,外观看上去很霸气,于是加了销售的微信,预约了第二天的试驾。

试驾后的体验确实还可以,问了一下知道是BYD的车

BYD的车到还有个好处,车机开adb折腾方便

福特智趣烈马(云)

这个车处于发布但是没有开售,不过我还挺喜欢的,所以在这里云一下

BRONCO 作为美系车驾驶方面不会差

但是他是个增程车,高速油耗比插混高(废话,你都买美系了还在意油耗?)

越野方面作为老牌美系车,给的比钛7多,还给了个全尺寸备胎

从已发布的信息上看是个好车但是还在预售中,买不到也试不到

确定购买与提车

说实话,试完之后感觉方盒子车真的视野好,且空间大更舒适,所以于 10.19下订, 11.04提车,相对于之前刚开始想的三台车(30W左右),实际上是省钱了哈哈

提车流程反正就那一套,方程豹的客餐还可以,不过橘子是酸酸的

主要是原先自己想要的三台车试驾后,都有些当时不可接受的问题,这个车正好还挺符合我各方面爱好和习惯的,而且比亚迪的三电技术也不错

1000KM 后

一千公里其实也没多少,开出去和朋友在钱塘江钓鱼玩玩之类的,然后从杭州开次高速回台州老家就差不多了。

底盘上,没有之前开A6L的信心足,跑一次高速就很明显能感受到,不过这两车也不在一个价位,这车二十来万,快一米九高,哪怕电池在车底带来天然的稳定性,和能买两台钛7的A6L对比确实有点欺负他了

动力上,不得不说这套插混系统真的是天才,太有力了兄弟,这也是电机系统领先于内燃机的地方

操控,灵活,好

红米 AX6000 刷入 OpenWRT 和 Uboot

2023年10月18日 20:30
Featured image of post 红米 AX6000 刷入 OpenWRT 和 Uboot

今日 OpenWRT23.05 正式版终于发了,MT7986 和 MT7981 系列芯片终于有 OP 的正式版支持了,于是就海鲜市场三百大洋收了一台 Redmi AX6000 应该是最便宜的 MT7986 路由器了(以及还是 openwrt.org 上文档 最详细的一款 MT7986 路由器)

打开原厂固件的SSH

降级(如果您准备直接TTL刷可以不看这里)

首先先要将路由器降级到 1.0.48 版本固件 在小米的升级界面可以直接选择旧版固件降级,然后系统会告诉你禁止降级,此时看到浏览器上方链接有个 downgrade= 如果后面的数字是 0 则改成 1,是 1(见于 1.0.64 版本固件)则改成 2

打开调试模式

进入 WebUI,登陆后看到的 URL 类似于

1
http://你的路由器IP/cgi-bin/luci/;stok={token}/后面一堆东西

然后将链接改成

1
http://你的路由器IP/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20echo%20pVoAAA%3D%3D%20%7C%20base64%20-d%20%7C%20mtd%20write%20-%20crash%20%3B%20

这样将会在路由器中执行 echo pVoAAA== | base64 -d | mtd write - crash,然后使用

1
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20

来重启路由器

修改 Bdata

重新登陆路由器 WebUI 此时 token 有变化,记得不要使用之前的链接操作

1
http://你的路由器IP/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20set%20telnet_en%3D1%20%3B%20bdata%20set%20ssh_en%3D1%20%3B%20bdata%20commit%20%3B%20

这条在路由器中执行 bdata set telnet_en=1 ; bdata set ssh_en=1 ; bdata commit

然后使用

1
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20

来重启路由器

接着就可以 telnet 连接路由器了

打开 SSH

首先 telnet 连接到路由器,看到经典的 ARE U OK 彩蛋

然后用 vi 删除 /etc/init.d/dropbear 中 135 行到 137 行,其中内容是

1
2
3
if [ "$flg_ssh" != "1" -o "$channel" = "release" ]; then        
  return 0                                                           
fi

然后使用 /etc/init.d/dropbear start 来启动 dropbear 服务

接着用 passwd 来设置 root 账户的密码后就可以用SSH连接到路由器啦~

安装原厂分区的 OpenWRT

设置启动分区

首先我们使用 cat /proc/mtd 来查看原厂分区长什么样子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
root@XiaoQiang:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 08000000 00020000 "spi0.1"
mtd1: 00100000 00020000 "BL2"
mtd2: 00040000 00020000 "Nvram"
mtd3: 00040000 00020000 "Bdata"
mtd4: 00200000 00020000 "Factory"
mtd5: 00200000 00020000 "FIP"
mtd6: 00040000 00020000 "crash"
mtd7: 00040000 00020000 "crash_log"
mtd8: 01e00000 00020000 "ubi"
mtd9: 01e00000 00020000 "ubi1"
mtd10: 03200000 00020000 "overlay"

有两个启动分区,类似于 AndroidAB 分区

然后使用 cat /proc/cmdline 来查看当前的启动分区,得到类似以下结果

1
2
root@XiaoQiang:~# cat /proc/cmdline
console=ttyS0,115200n1 loglevel=8 firmware=1 factory_mode=1 uart_en=1

如果 firmware=1 当前启动分区为 ubi1,如果 firmware=0 ,当前启动分区为 ubi

以我手上这台 firmware=1 为例,设置下一次的启动分区为 ubi 也就是 mtd8

1
2
3
4
5
6
7
8
root@XiaoQiang:~# nvram set boot_wait=on
root@XiaoQiang:~# nvram set uart_en=1
root@XiaoQiang:~# nvram set flag_boot_rootfs=0
root@XiaoQiang:~# nvram set flag_last_success=0
root@XiaoQiang:~# nvram set flag_boot_success=1
root@XiaoQiang:~# nvram set flag_try_sys1_failed=0
root@XiaoQiang:~# nvram set flag_try_sys2_failed=0
root@XiaoQiang:~# nvram commit

刷入 initramfs

然后为路由器刷入 initramfs 后重启, 我这里为了确保不受到国际互联网连接的影响,直接在本机起了一个 Nginx,互联网连接好的话也可以直接 wget op 的官方源

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
root@XiaoQiang:/tmp# wget http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-stock-initramfs-factory.ubi
Connecting to 本机IP (本机IP:80)
openwrt-23.05.0-medi 100% |*********************************************************************************************|  8320k  0:00:00 ETA
root@XiaoQiang:/tmp# ubiformat /dev/mtd8 -y -f /tmp/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-stock-initramfs-factory.ubi 
ubiformat: mtd8 (nand), size 31457280 bytes (30.0 MiB), 240 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 239 -- 100 % complete  
ubiformat: 240 eraseblocks have valid erase counter, mean value is 0
ubiformat: flashing eraseblock 64 -- 100 % complete  
ubiformat: formatting eraseblock 239 -- 100 % complete  
root@XiaoQiang:/tmp# reboot
root@XiaoQiang:/tmp# Connection closing...Socket close.

Connection closed by foreign host.

其实这一步之后就可以直接跳到 uboot 然后刷入 ubootmod 固件,但是这样风险比较高,如果想这样做的话,这里直接刷入 ubootmod-initramfs-factory.ubi 固件然后直接跳到下一步

设置 uboot-env

这里用于设置总是于 system 0 启动

1
2
3
4
5
6
7
8
fw_setenv boot_wait on
fw_setenv uart_en 1
fw_setenv flag_boot_rootfs 0
fw_setenv flag_last_success 1
fw_setenv flag_boot_success 1
fw_setenv flag_try_sys1_failed 8
fw_setenv flag_try_sys2_failed 8
fw_setenv mtdparts "nmbm0:1024k(bl2),256k(Nvram),256k(Bdata),2048k(factory),2048k(fip),256k(crash),256k(crash_log),30720k(ubi),30720k(ubi1),51200k(overlay)"

然后随意使用 WebUI 或者是 sysupgrade 指令安装 OpenWRT

这一步做完当 AP 什么的就已经可以用了,如果你要在上面安装 114514 个软件或者只是觉得官方分区傻逼,想来点开源的 Openwrt U-boot 的话可以接着往下看

安装 ubootmod 分区的 OpenWRT

备份

可以用 WebUI 的备份或者 cat 后 ZMODEM 传输

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
root@OpenWrt:~# opkg update
# 这里太长略过
root@OpenWrt:~# opkg install lrzsz
Installing lrzsz (0.12.21-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.0/packages/aarch64_cortex-a53/packages/lrzsz_0.12.21-1_aarch64_cortex-a53.ipk
Configuring lrzsz.
root@OpenWrt:~# cat /dev/mtdblock0 > /tmp/BL2.bin
root@OpenWrt:~# sz /tmp/BL2.bin 

root@OpenWrt:~# cat /dev/mtdblock1 > /tmp/Nvram.bin
root@OpenWrt:~# sz /tmp/Nvram.bin 
rz
root@OpenWrt:~# cat /dev/mtdblock2 > /tmp/Bdata.bin
root@OpenWrt:~# sz /tmp/Bdata.bin 

root@OpenWrt:~# cat /dev/mtdblock3 > /tmp/Factory.bin
root@OpenWrt:~# sz /tmp/Factory.bin 
rz
root@OpenWrt:~# cat /dev/mtdblock4 > /tmp/FIP.bin
root@OpenWrt:~# sz /tmp/FIP.bin 
rz

查看当前分区(非必须,但是保险起见看一眼)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
root@OpenWrt:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00100000 00020000 "BL2"
mtd1: 00040000 00020000 "Nvram"
mtd2: 00040000 00020000 "Bdata"
mtd3: 00200000 00020000 "Factory"
mtd4: 00200000 00020000 "FIP"
mtd5: 00040000 00020000 "crash"
mtd6: 00040000 00020000 "crash_log"
mtd7: 01e00000 00020000 "ubi_kernel"
mtd8: 05000000 00020000 "ubi"

刷入 ubootmod initramfs

依旧是本地起的 Nginx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
root@OpenWrt:~# wget http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-factory.ubi
Downloading 'http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-factory.ubi'
Connecting to 本机IP:80
Writing to 'openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-factory.ubi'
openwrt-23.05.0-medi 100% |*******************************|  8320k  0:00:00 ETA
Download completed (8519680 bytes)
root@OpenWrt:~# ubiformat /dev/mtd7 -y -f ./openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-factory.ubi 
ubiformat: mtd7 (nand), size 31457280 bytes (30.0 MiB), 240 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 239 -- 100 % complete  
ubiformat: 240 eraseblocks have valid erase counter, mean value is 2
ubiformat: flashing eraseblock 64 -- 100 % complete  
ubiformat: formatting eraseblock 239 -- 100 % complete  

重启

再次查看当前分区(非必须,但是保险起见再看一眼)

1
2
3
4
5
6
7
8
root@OpenWrt:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00100000 00020000 "BL2"
mtd1: 00040000 00020000 "Nvram"
mtd2: 00040000 00020000 "Bdata"
mtd3: 00200000 00020000 "Factory"
mtd4: 00200000 00020000 "FIP"
mtd5: 07a80000 00020000 "ubi"

修改分区

安装并加载 kmod-mtd-rw 内核模块

1
2
3
4
5
6
root@OpenWrt:~# opkg update && opkg install kmod-mtd-rw
# 太长略过 
Installing kmod-mtd-rw (5.15.134+git-20160214-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.0/targets/mediatek/filogic/packages/kmod-mtd-rw_5.15.134%2bgit-20160214-2_aarch64_cortex-a53.ipk
Configuring kmod-mtd-rw.
root@OpenWrt:~# insmod /lib/modules/$(uname -r)/mtd-rw.ko i_want_a_brick=1

删除所有的崩溃转储文件以防止 OpenWRT Uboot 启动到恢复模式

1
rm -f /sys/fs/pstore/*

格式化 ubi 并且创建新的 uboot-env 分区

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
root@OpenWrt:~# ubidetach -p /dev/mtd5; ubiformat /dev/mtd5 -y; ubiattach -p /dev/mtd5
ubidetach: error!: cannot detach "/dev/mtd5"
           error 19 (No such device)
ubiformat: mtd5 (nand), size 128450560 bytes (122.5 MiB), 980 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 979 -- 100 % complete  
ubiformat: 880 eraseblocks have valid erase counter, mean value is 1
ubiformat: 96 eraseblocks are supposedly empty
ubiformat: warning!: 4 of 980 eraseblocks contain non-UBI data
ubiformat: warning!: only 880 of 980 eraseblocks have valid erase counter
ubiformat: mean erase counter 1 will be used for the rest of eraseblock
ubiformat: use erase counter 1 for all eraseblocks
ubiformat: formatting eraseblock 979 -- 100 % complete  
UBI device number 0, total 980 LEBs (124436480 bytes, 118.6 MiB), available 954 LEBs (121135104 bytes, 115.5 MiB), LEB size 126976 bytes (124.0 KiB)
root@OpenWrt:~# ubimkvol /dev/ubi0 -n 0 -N ubootenv -s 128KiB
Volume ID 0, size 2 LEBs (253952 bytes, 248.0 KiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "ubootenv", alignment 1
root@OpenWrt:~# ubimkvol /dev/ubi0 -n 1 -N ubootenv2 -s 128KiB
Volume ID 1, size 2 LEBs (253952 bytes, 248.0 KiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "ubootenv2", alignment 1

创建 OpenWrt U-Boot 的 NAND 恢复模式分区并刷入 ubootmod-initramfs-recovery.itb

这一步可选,不做也有 tftp 恢复模式可以用,可用空间也大一点

1
2
3
4
5
6
7
8
9
root@OpenWrt:~# ubimkvol /dev/ubi0 -n 2 -N recovery -s 10MiB
Volume ID 2, size 83 LEBs (10539008 bytes, 10.0 MiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "recovery", alignment 1
root@OpenWrt:~# wget http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-recovery.itb
Downloading 'http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-recovery.itb'
Connecting to 本机IP:80
Writing to 'openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-recovery.itb'
openwrt-23.05.0-medi 100% |*******************************|  7104k  0:00:00 ETA
Download completed (7274496 bytes)
root@OpenWrt:~# ubiupdatevol /dev/ubi0_2 ./openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-initramfs-recovery.itb 

刷入 OpenWRT U-boot

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
root@OpenWrt:~# wget http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-preloader.bin
Downloading 'http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-preloader.bin'
Connecting to 本机IP:80
Writing to 'openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-preloader.bin'
openwrt-23.05.0-medi 100% |*******************************|   200k  0:00:00 ETA
Download completed (205560 bytes)
root@OpenWrt:~# mtd write ./openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-preloader.bin BL2
Unlocking BL2 ...

Writing from ./openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-preloader.bin to BL2 ...     
root@OpenWrt:~# wget http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-bl31-uboot.fip
Downloading 'http://本机IP/AX6000/openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-bl31-uboot.fip'
Connecting to 本机IP:80
Writing to 'openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-bl31-uboot.fip'
openwrt-23.05.0-medi 100% |*******************************|   718k  0:00:00 ETA
Download completed (735409 bytes)
root@OpenWrt:~# mtd write ./openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-bl31-uboot.fip FIP
Unlocking FIP ...

Writing from ./openwrt-23.05.0-mediatek-filogic-xiaomi_redmi-router-ax6000-ubootmod-bl31-uboot.fip to FIP ...     

最后,用 WebUI 或者 sysupgrade 指令刷入 ubootmod-squashfs-sysupgrade 固件即可

解决 RouterOSv7 中的 PMTU 黑洞问题

2023年7月30日 19:40
Featured image of post 解决 RouterOSv7 中的 PMTU 黑洞问题

当我刚刚用 RB5009 替换掉之前的老 E3 后并配好了 IPv6

结果大概一小时后,室友突然闯进了我的房间,用我的电脑测试打开了 mail.qq.com

恐怖故事就此发生,我的电脑对此响应缓慢,而室友的电脑直接就无法打开

试了一下让猫猫头软件启用全局模式之后,世界又好了起来

我的第一反应是:鹅炸了?

那显然不是……

第二反应是 DNS 的问题,解析到了神必目标,遂把室友电脑的 DNS 改到 114

结果没用,不是这个原因(要不然也不会有这篇了……)

接着试了一下 ping mail.qq.com 发现解析到了IPv6地址,遂反应过来,是不是 PMTU 黑洞了

赶紧打开 http://icmpcheckv6.popcount.org/ 来测一下,结果全绿

ICMP black hole check

不过还是死马当成活马医了一下(主要是有点懒的监看一下流量,抓包看一眼)

1
/ipv6 firewall mangle add chain=forward out-interface=pppoe-out1 protocol=tcp tcp-flags=syn action=change-mss new-mss=clamp-to-pmtu

结果……结果真的活了!

问了下群友

用 Sqtracker 搭建PT站

2023年4月14日 16:38
Featured image of post 用 Sqtracker 搭建PT站

警告:发现了这东西在安全性上的一些隐患

起因

之所以会想到搭建个 PT 站是因为在 ACMer 垃圾佬交流群里群友们的突发奇想

最开始想用的是 gazelle 或 ZJUNexusPHP,但是显然这些程序都太古老了,经过一番 Github 冲浪,就找到了这个 NodeJS 写的 Sqtracker 在众多开源 PT 程序中还算比较符合我的审美

搭建

修改配置

如果按照官方的搭建方法其实只要git clone 然后 docker-compose up -d 就可以完成,但是由于其使用了我不是很喜欢的 traefik 并且 mongo 在本地,所以我们需要修改其docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
version: "3.9"
services:
  # traefik:
  #   image: "traefik:v2.5"
  #   container_name: "sq_traefik"
  #   command:
  #     - "--api.insecure=true"
  #     - "--providers.file=true"
  #     - "--providers.file.filename=/config/traefik.yml"
  #     - "--entrypoints.webinsecure.address=:80"
  #     - "--entrypoints.web.address=:443"
  #     - "--entryPoints.web.proxyProtocol.insecure"
  #     - "--entryPoints.web.forwardedHeaders.insecure"
  #     - "--certificatesresolvers.tlsresolver.acme.email=pt@acmer.info"
  #     - "--certificatesresolvers.tlsresolver.acme.storage=/letsencrypt/acme.json"
  #     - "--certificatesresolvers.tlsresolver.acme.httpchallenge=true"
  #     - "--certificatesresolvers.tlsresolver.acme.httpchallenge.entrypoint=webinsecure"
  #   ports:
  #     - "80:80"
  #     - "443:443"
  #     - "8080:8080"
  #   volumes:
  #     - "/var/run/docker.sock:/var/run/docker.sock:ro"
  #     - ./letsencrypt:/letsencrypt
  #     - ./traefik.yml:/config/traefik.yml
  # database:
  #   container_name: sq_mongodb
  #   image: mongo:6.0
  #   ports:
  #     - "127.0.0.1:27017:27017"
  #   volumes:
  #     - ./data:/data/db
  api:
    container_name: sq_api
    image: ghcr.io/tdjsnelling/sqtracker-api:latest
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - ./config.js:/sqtracker/config.js
    # depends_on:
    #   - database
  client:
    container_name: sq_client
    image: ghcr.io/tdjsnelling/sqtracker-client:latest
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - ./config.js:/sqtracker/config.js
      # - ./favicon.png:/sqtracker/public/favicon.png
      # - ./favicon.ico:/sqtracker/public/favicon.ico
    depends_on:
      - api

然后编辑 config.js 修改配置(这文件注释很详细了,看着改就行)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module.exports = {
  envs: {
    SQ_SITE_NAME: "ACMer PT",
    SQ_SITE_DESCRIPTION: "A Private Tracker site for Competitive programming player",
    SQ_CUSTOM_THEME: {
      primary: "#f45d48",
    },
    SQ_ALLOW_REGISTER: "open",
    SQ_ALLOW_ANONYMOUS_UPLOADS: false,
    SQ_MINIMUM_RATIO: 0.75,
    SQ_MAXIMUM_HIT_N_RUNS: 1,
    SQ_TORRENT_CATEGORIES: {
      Videos: [],
      Problems: [],
      Books: [],
      Misc: [],
    },
    SQ_BP_EARNED_PER_GB: 1,
    SQ_BP_EARNED_PER_FILLED_REQUEST: 1,
    SQ_BP_COST_PER_INVITE: 3,
    SQ_BP_COST_PER_GB: 3,
    SQ_SITE_WIDE_FREELEECH: false,
    SQ_ALLOW_UNREGISTERED_VIEW: false,
    SQ_EXTENSION_BLACKLIST: ["exe"],
    SQ_BASE_URL: "https://pt.acmer.info",
    SQ_API_URL: "https://pt.acmer.info/api",
    SQ_MONGO_URL: "不告诉你喵",
    SQ_MAIL_FROM_ADDRESS: "pt@acmer.info",
    SQ_SMTP_HOST: "SMTP邮件服务器",
    SQ_SMTP_PORT: 587,
    SQ_SMTP_SECURE: false,
  },
  secrets: {
    SQ_JWT_SECRET: "不告诉你喵",
    SQ_SERVER_SECRET: "不告诉你喵",
    SQ_ADMIN_EMAIL: "你的邮件喵",
    SQ_SMTP_USER: "pt@acmer.info",
    SQ_SMTP_PASS: "SMTP邮件密码喵",
  },
};

接着docker-compose up -d即可

Nginx 配置

阅读仓库中的 traefik.yml 发现要反代 / /api 以及 /sq

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
server {
    listen 80; # 这里开80仅用于测试,测试完成后要套上SSL
    server_name pt.acmer.info;

    location / {
	proxy_pass http://localhost:3000/;
        proxy_http_version                1.1;

        # Proxy Headers
        proxy_set_header Upgrade          $http_upgrade;
        proxy_set_header Host             $host;
        # proxy_set_header Connection       $connection_upgrade;
        proxy_set_header X-Real_IP        $remote_addr;
        proxy_set_header X-Real-Host      $host;
        proxy_set_header X-Forwarded-For  $remote_addr;
    }

    location ^~ /api/ {
        proxy_pass http://localhost:3001/;
	proxy_http_version                1.1;

        # Proxy Headers
        proxy_set_header Upgrade          $http_upgrade;
        proxy_set_header Host             $host;
        # proxy_set_header Connection       $connection_upgrade;
        proxy_set_header X-Real_IP        $remote_addr;
        proxy_set_header X-Real-Host      $host;
        proxy_set_header X-Forwarded-For  $remote_addr;
    }

    location ^~ /sq/ {
        proxy_pass http://localhost:3001;
        proxy_http_version                1.1;

        # Proxy Headers
        proxy_set_header Upgrade          $http_upgrade;
        proxy_set_header Host             $host;
        # proxy_set_header Connection       $connection_upgrade;
        proxy_set_header X-Real_IP        $remote_addr;
        proxy_set_header X-Real-Host      $host;
        proxy_set_header X-Forwarded-For  $remote_addr;
    }

}

注意这里的 /sq/ 反代位置是不需要反斜杠的

Incomplete certificate chain prevents ClashForAndroid from connecting to TLS proxies

2023年1月1日 04:18
Featured image of post Incomplete certificate chain prevents ClashForAndroid from connecting to TLS proxies

Over the past few days , ClashForAndroid could not connect TLS proxies. The reason was found in the log

1
x509: vertificate signed by unknown authority

And , This config.yaml works well on Windows/Arch Linux/macOS/iOS(Stash)

At first, I wondered if the RootCA of my certificate was not trusted by Android? But using Chrome/Edge to access the https page built with the same certificate shows that the certificate is trusted.

After asking a friend who is an Android developer, he said: “Since Android 7.0, third-party applications do not trust manually installed root certificates by default.”

However, this RootCA is not installed manually. It is ISRG Root X1 directly built into the system. (I use the certificate issued by Let’s Encrypt)

Then I saw an article that solved the problem: 如何补全 SSL 证书链?

通常情况下 PC 端浏览器都可以通过 Authority Info Access(权威信息访问)的 URL 链接获得中间证书,但在部分 Android 系统的浏览器上访问时会出现证书不可信或无法访问等问题。

主要原因在于部分 Android 系统的浏览器并不支持通过 Authority Info Access(权威信息访问)的 URL 链接获得中间证书,这时您需要把证书链文件按照 SSL 证书链的结构合并为一个文件重新部署到服务器上,浏览器在与服务器连接时将会下载用户证书和中间证书,使您的浏览器访问时显示为可信证书。

After using fullchain.cer , the proxies can connect normally. Chrome/Edge on Android can visit website with intermediate certificate because it has built-in “Authority Info Access” capabilities.

Tips: In some versions of OpenWRT, it is also not supported to automatically download and complete intermediate certificates through “Authority Info Access”.

一次docker与ufw规则冲突问题

2022年7月26日 19:15
Featured image of post 一次docker与ufw规则冲突问题

起因

把NodeStatus迁移到一台不用的VPS上,做好反代后ufw deny 35601,但是在我设置完ufw后,35601端口依旧是可以访问的

然后我迷惑的Google了一小时,发tg问了涩队木得回应,就去睡觉了

经过

在一顿瞎折腾发现systemd里的iptables服务没启动后就systemctl enable iptablessystemctl start iptables

发现这玩意又好用了,于是很开心的告诉涩队我好像找到问题所在了,然后涩队:“?没有enable是什么操作,这东西要enable?那个是iptables恢复的开机服务”

我:“?????”

然后systemctl cat iptables看了一下

草!然后我试着还原现场后手动/usr/bin/iptables-restore /etc/iptables/iptables.rules了一下,发现也好了

怪哦

结果

经过涩队点拨,发现是docker的问题,ufw deny了之后,docker又重新把端口打通了草

把docker-compose.yml里面ports从"35601:35601"改成"127.0.0.1:35601:35601"就好了

NECPC 2022 (第16届CCPC东北四省赛)

2022年6月1日 15:42
Featured image of post NECPC 2022 (第16届CCPC东北四省赛)

校内选拔

其实可以直接要个名额打,但是还是打了一下实验室的选拔,然后发现题用的是NECPC2020 这也就是我为啥2022年写了NECPC2020的博客

然后单打手速没组队的快校内RANK2

训练

我和yz的训练……那一定是没有的,长春封了那么多天,一直在学考研和摸鱼,考研已经上岸的文哥在写毕设和自己一个人练

赛前我唯一的训练应该就是打了Codeforces Round #789 (Div. 2)

Codeforces Round #789 (Div. 2)

疫情

这次NECPC不得不说疫情了,首次体验异地三人三机

不过长春封了那么多天,我反正已经麻了,没啥说的了

但是对于打比赛来说,异地打沟通是真的麻烦,就像是写个公式,线下我可以直接写草稿纸,线上我只能腾讯会议共享屏幕然后VSCode开个md打公式然后预览

过程

签到丝滑的一比

然后文哥的BFS写炸了,我类似记搜的一个东西也炸了,调试调麻了,摸了

看了下B.Capital Program 是个傻逼题就干过去了

然后嘛,然后我们三个人就打出了各自在NECPC的最差成绩铜哈哈

我记得我大二刚开始打ACM的时候,打星单挑NECPC2020也有银尾的样子

不过好像嘻嘻哈哈的,大家打的也挺欢乐(

反正没有任何训练,既然做好了摸鱼的准备的话,开心最重要qwq

Codeforces Round #789 (Div. 2)

2022年5月9日 10:36
Featured image of post Codeforces Round #789 (Div. 2)

https://codeforces.com/contest/1678

A.Tokitsukaze and All Zero Sequence

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int n;
int a[MAXN];

inline void work(signed CASE=1,bool FINAL_CASE=false) {
    n=read();
    int zero=0;
    set<int> s;
    for(int i=1;i<=n;i++) {
        int x=read();
        zero+=(x==0);
        s.insert(x);
    }
    if(zero) {
        printf("%d\n",n-zero);
        return;
    }
    int k=n-sz(s);
    if(k==0) {
        printf("%d\n",n+1);
    } else {
        printf("%d\n",n);
    }
    return;
}

signed main() {
    // ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed CASE=1; CASE<=T; CASE++) { //
        //printf("Case #%d: ",CASE); //printf("Case %d: ",CASE); //printf("Case #%d: \n",CASE); //printf("Case %d: \n",CASE);
        work(CASE,CASE==T);
        if(CASE!=T) {}
    }
    return 0;
}

B1.Tokitsukaze and Good 01-String (easy version)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int n,ans;
bool flag;
char lst=0;

inline void work(signed CASE=1,bool FINAL_CASE=false) {
    n=read(); vector<int> v;
    for(int i=1;i<=n;i++) {
        char c=nc();
        if(c==lst) {
            v.back()++;
        } else {
            v.pb(1);
            lst=c;
        }
    }
    for(auto x:v) {
        if(x&1) {
            flag=!flag;
        }
        ans+=flag;
    }
    printf("%lld\n",ans);
    return;
}

signed main() {
    // ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed CASE=1; CASE<=T; CASE++) { //
        //printf("Case #%d: ",CASE); //printf("Case %d: ",CASE); //printf("Case #%d: \n",CASE); //printf("Case %d: \n",CASE);
        work(CASE,CASE==T);
        if(CASE!=T) {
            ans=0;
            flag=false;
            lst=0;
        }
    }
    return 0;
}

B2.Tokitsukaze and Good 01-String (hard version)

一开始没找出B2规律,然后被带飞

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
int n,ans,ls=-1,cnt;
bool flag;
char lst=0;

inline void work(signed CASE=1,bool FINAL_CASE=false) {
    n=read(); vector<int> v;
    for(int i=1;i<=n;i++) {
        char c=nc();
        if(c==lst) {
            v.back()++;
        } else {
            v.pb(1);
            lst=c;
        }
    }
    for(auto &x:v) {
        if(x&1) {
            flag=!flag;
            x=(x==1)?0:x;
        } else if(flag) {
            x=(x==2)?0:x;
        }
        ans+=flag;
    }
    for(int i=0;i<sz(v);i++) {
        if(0!=v[i] && ls!=(i&1)) {
            ls=i&1;
            cnt++;
        }
    }
    printf("%lld %lld\n",ans,cnt>1?cnt:1);
    return;
}

signed main() {
    // ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed CASE=1; CASE<=T; CASE++) { //
        //printf("Case #%d: ",CASE); //printf("Case %d: ",CASE); //printf("Case #%d: \n",CASE); //printf("Case %d: \n",CASE);
        work(CASE,CASE==T);
        if(CASE!=T) {
            lst=cnt=ans=0;
            flag=false;
            ls=-1;
        }
    }
    return 0;
}

C.Tokitsukaze and Strange Inequality

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int n,ans;
int a[MAXN];
int f[5009][5009];

inline void work(signed CASE=1,bool FINAL_CASE=false) {
    n=read();
    for(int i = 1; i <= n; i++) {
        a[i]=read();
    }
    for(int i = 1; i <= n; i++) {
        f[i][n] = a[n] < a[i];
        for(int j = n - 1; j >= i + 1; j--) {
            f[i][j] = f[i][j + 1] + (a[j] < a[i]);
        }
    }
    for(int i = 2; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            f[i][j] += f[i - 1][j];
        }
    }
    for(int i=1;i<=n;i++) {
        for(int j=i+1;j<=n;j++) {
            if(a[j]>a[i]) {
                int l=i+1,r=j-1;
                if(l<=r && r<n-1) {
                    ans+=(f[r][r + 2] - f[l - 1][r + 2]);
                }
            }
        }
    }
    printf("%lld\n",ans);
    return;
}

signed main() {
    // ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=(signed)read();//scanf("%d",&T);//cin>>T;
    for(signed CASE=1; CASE<=T; CASE++) { //
        //printf("Case #%d: ",CASE); //printf("Case %d: ",CASE); //printf("Case #%d: \n",CASE); //printf("Case %d: \n",CASE);
        work(CASE,CASE==T);
        if(CASE!=T) {
            ans=0;
        }
    }
    return 0;
}

魔改华为 MA5671A 和 Nokia G-010S-A

2021年12月27日 00:05
Featured image of post 魔改华为 MA5671A 和 Nokia G-010S-A

2021-12-27 更新

这玩意现在在国内论坛已经烂大街了


事情的起因是因为上学期结束暑假回家的时候,移动给小区的用户设备升级,然后给我家的设备换成了菊花的 HS8145V5,虽然这款设备本身的性能没什么好黑的,比之前的光猫强多了,但是这玩意在我的弱电箱内占了很大一块地方让我很不爽来着,而且 WLAN SSID 强制带 CMCC

最无话可说的是,移动的人把我原来的软路由和AP直接拆了,麻了

暑假的时候训练,camp,帮孙老师上课(实际上大头是摸鱼)这一套下来都没空搞家里的网络,就一直咕到了寒假

然后给我有两个选择就是

  1. 低成本方案:把华为的光猫刷回原版固件改桥接接入软路由,然后继续用(毕竟这玩意性能还凑合)
  2. 硬件更换方案:换掉华为的光猫,直接在软路由上整 PON Stick,可以节约弱电箱的空间

最后还是选了方案2,HS8145V5 最大的问题是热。。虽然性能完全达标,但是真的很热,并且多一个设备让我的走线强迫症发作了

因此在瞎翻 OpenWRT 论坛和大黄鱼之后发现了神奇的洋垃圾模块 华为 MA5671A 和 Nokia G-010S-A (还有一个 G-010S-P)

于是脑子一热下单 Intel 82599 和一个拆机的 G-010S-A

为什么说是脑子一热呢

这个东西。。。完全不能在中文网站上搜到相关结果

并且没有提供 Datasheet ,Google 能找到相关资料的地方只有

Will GPON Nokia G-010S-A change sn? - Hardware Questions and Recommendations - OpenWrt Forum

Nokia G-010S-A Pin 6 Issue (rsaxvc.net)

hwti/G-010S-A: All about Nokia G-010S-A GPON SFP (github.com)

并且买完才发现 G-010S-A 用的光缆是 APC (斜切,外观为绿色端子)(顺带一提,MA5671A 也是 APC)

而我家的入户光纤是 UPC (平切,外观为蓝色端子)的,靠谱起见大概我还需要去借一台熔纤机或者买个转接光纤这样

以及还有个坑点是,G-010S-A,G-010S-P,MA5671A 支持到2.5Gpbs 的 GPON,但是 Intel 82599 只提供 1Gpbs/10Gpbs 两种速率选择,也就是说,只能工作在1Gpbs上,但是这个价格捡垃圾没有其他选择了(

然后嘛……就是等待31号飞机飞回家里装咯,过两天再更新

其实折腾好了,但是我摸了,就咕了qwq

2022年的Update,你们以为我咕了,但是实际上我没咕,这何尝也是不是一种咕捏

G-010S-A 这个猫棒,要按照上面给出的 Nokia G-010S-A Pin 6 Issue (rsaxvc.net) 这篇里面进行一个改造,才能兼容我的 Intel X520-DA2 网卡,改完之后是这样的

然后……然后就直接按 hwti/G-010S-A 上直接配好 SN 和 Password 就行了,家里宽带光猫装机的时候我直接问师傅要了全部接入数据,也就没有破解光猫这种问题了捏

至于华为 MA5671A 捏,不知道啥时候想写,这个就是要自己找个OP固件,拿 Flash 编程器刷进去就好了,稍微复杂一些,但是也很简单

MA5671A和G-010S-A其实是同方案的产品,但是固件不通用,有些小细节不同,MA5671A不用物理魔改电路这样

UPC和APC光纤的问题我最后是五块钱一条无源光转换线解决的

ICPC 2014 Xian F Color

2021年5月27日 18:27

https://codeforces.com/gym/100548/problem/F

题目大意

$N$朵花排成一行,我们有$M$种颜色,可以给这些花涂色,保证相邻的花的颜色不同

求最后恰好使用了$k$种颜色的方案数。

推算

第一反应就是 $\complement_m^k\ast\ k\left(k-1\right)^{n-1}$ 当想了一下之后好像不对,这个公式算出来的是使用小于等于$k$种颜色的方案数量

然后推出如下公式 $\complement_k^x\ast x\left(x-1\right)^{n-1}$ 这个公式的含义是从$k$种颜色中再选出来$x$种使得相邻的格子不同色最后的颜色数小于等于$x$,每一个集合都有交,用容斥原理来处理

设 $S = F[x]=\complement_k^x\ast x\left(x-1\right)^{n-1}$

$ans=\complement_m^k\sum\left(-1\right)^{k-i}\complement_k^i\ast\ i\left(i-1\right)^{n-1}$

记得开long long

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include<bits/stdc++.h>
#define int long long//__int128
#define mmst0(x) memset(x,0,sizeof(x))
#define mmst3f(x) memset(x,0x3f,sizeof(x))
#define pb(x) emplace_back(x)
#define mkp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef long double rld;
typedef unsigned long long ull;

const rld eps = 1e-6;
const int INF=0x3f3f3f3f;//0x3f3f3f3f3f3f3f3f;//LLINF
const int N=(int)1e6+10,mod=1e9+7;

int read(){int s=0,w=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();} return s*w;}
//void prt(int x){if(x<0){putchar('-');x=-x;}if(x>9)prt(x/10);putchar((char)(x%10+'0'));}

int n,m,k;
int inv[N]={0,1},c[N]={1};

int qpow(int a ,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}

void get_combine(int x)
{
    for(int i=1;i<=k;i++) c[i]=(c[i-1]*(x-i+1)%mod)*inv[i]%mod;
}

inline int calc(int x)
{
    return (c[x]*x%mod)*qpow(x-1,n-1)%mod;
}

void work()
{
    n=read();m=read();k=read();
    get_combine(m);
    int ans=c[k],ans1=0,flag=1;
    get_combine(k);
    for(int i=k;i>=1;i--)
    {
        ans1=(ans1+flag*calc(i)+mod)%mod;
        flag=-flag;
    }
    ans=ans*ans1%mod;
    cout<<ans<<endl;
    return;
}

signed main()
{
    for(int i=2;i<N;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    //ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); //freopen(".in", "r", stdin);//freopen(".out", "w", stdout);
    signed T=(int)read();
    for(signed Case=1; Case<=T; Case++)
    {
        printf("Case #%d: ",Case);
        work();
    }
    return 0;
}

迷茫之路

2019年11月19日 22:29

致来自2022年后来的你:这篇文章狗屁不通,请寄存脑子之后再看


不知道为什么开始写这篇回忆,开始写一些狗屁不通,随心所欲的文字。

现在是NOIP2019结束的日子emmmm,现在叫做CSP

大概是我正式离开算法竞赛的一年后,2019年,我大一,也没想着打ACM

退役确实是一件难受的事情。那种感觉我至今还记得,曾经的我一直觉得,在机房就是我的全世界,退役之后有时候就会感到很迷茫,甚至连学习的目标也找不到,当然,这可能会涉及到一些我的情感方面,分手什么的也将我变得比以前冷漠了些吧。

不过在现在回想,我们喜欢的可能不是OI这件事情本身,而是和一群追寻梦想的孩子一起,做些“我觉得我要为了她献身,哪怕是提前预支我们的未来”

我觉得我们曾经高中机房里的同学们,若是用学OI的精力投身文化课的话,会怎样呢

文化课虽说令人烦恼,但在一年的时间里苦中作乐,就可以进入大学的生活了,可以去做一些令自己愉快的事情啦。

到了大学,买了相机,喜欢上了拍风景,说实话,到了大学之后,我大概是有空闲时间就会去在新的城市里寻找着没有见过的风景。心态比高考的时候平和很多。当然,我说实话我在大学荒废了很多东西。大学第一学期的文化课没有好好去学习什么。

回忆一下竞赛到底给我带来了什么?一切都是只能在高中三年罢了吧。到了大学,一切如过眼烟云,实际上竞赛只留给我一种精神上的鼓励罢了。是的啊,喜欢一件事,为之狂奔,沿途风景再美,也不能比的起你的灵魂所向。这就是青春的感觉吧!

退役了之后无数次回忆OI,其实说实话回忆的是机房里的生活,也就是回忆热血的过去。

未来不可预知,人类是宇宙中的沙砾,我们在蓝天中流浪,陪伴着我们的心灵家园。我们到底是为了什么呢存在于这个时间,这个世界之中?

答案不可预知,起码在我们现在的科学中不可预知。

但是人类依旧一往直前。我们依旧会一往直前。

BCM20702A1在Ubuntu下无法连接设备

2019年11月4日 22:03

给X230换了张DW1550网卡,其实就是戴尔版的BCM94352网卡==

试了一下刷白名单BIOS和Coreboot,感觉Coreboot还是有点问题,还是用魔改白名单BIOS了

然后屏蔽51脚,拆掉机器自带的蓝牙模块(BCM92070MD),网卡在Ubuntu里面安装bcmwl-kernel-source正常工作,然后遇到一个蛇皮问题,就是虽然网卡附带的蓝牙(BCM20702A1)识别正常,但是很蛋疼的是可以和设备配对但是不能连接==

dmesg截图

看样子是缺少了文件==

最后从redhat的bug报告上面找到了解决方法==,askUbuntu上面都没啥软用,redhat还是牛逼

https://bugzilla.redhat.com/show_bug.cgi?id=1264153

上面说的蛮麻烦的==,要从Windows驱动里面掏出文件然后转格式==

实际上Github上有大佬已经帮忙转制好了qwq

1
sudo wget --tries=3 --timeout=120 https://github.com/winterheart/broadcom-bt-firmware/raw/master/brcm/BCM20702A1-413c-8143.hcd -P /lib/firmware/brcm

reboot

一条指令完事~\ (≧▽≦) /~

当然,如果你的机器也出现这个问题的话,你要根据你序号的不同选择不同的文件==

❌
❌