zoukankan      html  css  js  c++  java
  • 2019组队赛第四场(2018湖南省第14届大学生计算机程序设计竞赛)解题报告 Apare_xzc

    2019组队赛第四场 解题报告

    (2018湖南省第14届大学生计算机程序设计竞赛) 解题报告

    by lj zx xzc

    2019/4/2

    前言:

    xzc:
      这次周赛大的不是很爽,我觉得有一部分原因是我们的状态不好,思维没有很活跃吧。 可能大家都没睡午觉吧。
      这场比赛我们队出了3到题,一道签到,一道模拟?一道猜想,剩下的时间都在卡K题和B题。(B题zyw骗我们说他可以进化成dp手,我们一直在推传统的加减乘除的dp…)当时大家都没有往完全平方数的找规律的方向去想。
      K题是因为没有memset所以wa,后来我也wa了几发,应该是前缀和的边界没处理好
      J题是我的锅,当时lj跟我说它就是一颗树,可以做,但是我当时在卡B题,没有去开这道题,(当时我觉得zyf+zyw做了半天才做出来,我们短时间不一定能AC…),其实dfs还挺好写的
      还有我们队一般是过了样例就交,有时候1A的非常爽,但是wa起来会罚时爆炸的
      我觉得这些都是小问题,平时暴露出来也好,多注意,及时改掉就好啦,总比现场赛出锅要强。
      我们队还是很厉害的!大家加油呀!
      只要大家平时好好刷题,比赛头脑清醒,也可以像twt他们队一样nb的! 冲鸭!


    vjudge链接: CCNUACM Team Contest 2019 Round #4


    A.字符画

    签到题

    #include <bits/stdc++.h>
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define LL long long
    #define MP make_pair
    #define pb push_back
    using namespace std;
    const int maxn = 1e5+100;
    char a[5][20] = {"oooooooooooo","..oo.o.o.o.o",
    "oooo.o.o.ooo","o..o.o.o.o.o","oooooooooooo" }; 
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int w;
        cin>>w;
        for(int i=0;i<5;++i)
        {
        	printf("%c%c%c",a[i][0],a[i][1],a[i][2]);
        	int cnt = 3;
        	for(int t=1;t<=3;t++)
        	{
        		for(int u=0;u<w;++u)
        		printf(".");
        		for(int p=0;p<3;p++)
        			printf("%c",a[i][cnt++]);
    		}
    		printf("
    ");
    	}
        return 0;
    }
    

    B.2018
    题面:

    Bobo 想统计满足下面条件的矩阵 A 的数量。
    
    矩阵 A 有 n 行 m 列,每个元素都是正整数。第 i 行第 j 列的元素用 Aij 表示。
    A1, 1 = 2018.
    对于所有 2 ≤ i ≤ n, 1 ≤ j ≤ m,Ai, j 是 Ai − 1, j 的约数。
    对于所有 1 ≤ i ≤ n, 2 ≤ j ≤ m,Ai, j 是 Ai, j − 1 的约数。
    因为满足条件的矩阵 A 数量很多,Bobo 只想统计满足条件的矩阵数量除以 (109 + 7) 的余数。
    
    1 ≤ n, m ≤ 2000
    数据组数不超过 105.
    Input
    输入文件包含多组数据,请处理到文件结束。
    
    每组数据包含 2 个整数 n 和 m.
    
    Output
    对于每组数据输出 1 个整数表示所求的数量除以 (1E9+7) 的余数。
    
    Sample Input
    1 1
    1 2
    2 2
    2 3
    2000 2000
    Sample Output
    1
    4
    25
    81
    570806941
    Hint
    对于第二组样例(n=1, m=2),满足条件的矩阵 A 有 (2018,2018),(2018,1009),(2018,2),(2018,1) 共 4 种。
    

    解法:

    • 观察得都是完全平方数,然后猜想规律
    • ans[i][j] = dp[i][j]^2
    • dp[i][j] = dp[i-1][j] + dp[i][j-1]+1
      无语了。。。

    代码:

    #include <bits/stdc++.h>
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define LL long long
    using namespace std;
    const int maxn = 2005;
    const int mod = 1e9+7;
    LL dp[maxn][maxn]; 
    int main()
    {
    	For(i,1,2000) dp[1][i] = dp[i][1] = i;
    	For(i,2,2000)
    		For(j,2,2000)
    			dp[i][j] = (dp[i-1][j]+dp[i][j-1]+1)%mod;
    	int x,y;
    	while(scanf("%d%d",&x,&y)!=EOF)
    	{
    		LL ans = dp[x][y]*dp[x][y]%mod;
    		printf("%lld
    ",ans);	
    	} 
    	return 0;
    }
    

    C.时间旅行
    题面都懒得挂了,这题也是猜想题
    zyf巨巨证明出来了
    他过了,我们其它两个队也跟着都过了…

    int main()
    {
    	//freopen("in.txt","r",stdin);
       	//freopen("out.txt","w",stdout);
    	LL c,h;
    	while(scanf("%lld%lld",&h,&c)!=EOF)
    	{
    		LL ans = 0;
    		if(c<h) ans = h;
    		else ans = c+1;
    		printf("%lld
    ",ans);
    	} 
    	return 0;
    }
    

    D.卖萌表情

    题面:

    已知以下 4 种都是卖萌表情(空白的部分可以是任意字符。竖线是便于展示的分隔符,没有实际意义):
    
    ^ ^ |  ^  | <  |  >
     v  | v v |  > | <
        |     | <  |  >
    给出 n 行 m 列的字符矩阵,Bobo 希望找出互不重叠的卖萌表情数量的最大值。互不重叠的意思是每个字符只属于至多一个卖萌表情。
    
    1 ≤ n, m ≤ 1000
    矩阵只包含 ^, v, <, > 4 种字符。
    n × m 的和不超过 2 × 106.
    Input
    输入文件包含多组数据,请处理到文件结束。
    
    每组数据的第一行包含 2 个整数 n 和 m.
    
    接下来 n 行的第 i 行包含长度为 m 的字符串,表示字符矩阵的第 i 行。
    
    Output
    对于每组数据输出 1 个整数表示互不重叠的卖萌表情数量的最大值。
    
    Sample Input
    2 4
    ^^^^
    >vv<
    2 4
    vvvv
    >^^<
    4 2
    v>
    <>
    <>
    ^>
    3 4
    ^>^>
    v
    >>>>
    Sample Output
    2
    0
    2
    2
    Hint
    第一组样例中有 2 个第一种卖萌表情。
    
    第四组样例中有 3 个卖萌表情,但是互不重叠的卖萌表情最多只有 2 个。
    

    分析:
    对每个矩阵的符号遍历,比对表情,比对成功,标记,计算得出结果

    代码:

    #include<cstdio>
    char str[1005][1005];
    int sign[1005][1005];
    int main()
    {
        int n,m,count;
        while(scanf("%d%d",&n,&m)!=EOF){
            count = 0;
            for(int i  =0;i < n;i++){
                scanf("%s",str[i]);
                for(int j = 0;j < m;j++) sign[i][j] = 0;
            }
            for(int i = 0;i < n;i++){
                for(int j = 0;j < m;j++){
                    if(sign[i][j]) continue;
                    if(str[i][j]=='^'){
                        if((i+1)<n&&(j-1)>=0&&(j+1)<m&&str[i+1][j-1]=='v'&&str[i+1][j+1]=='v'&&!sign[i+1][j-1]&&!sign[i+1][j+1]){
                            sign[i+1][j-1]=1;
                            sign[i+1][j+1]=1;
                            sign[i][j]=1;
                            count++;
                        }
                        else if((j+2)<m&&(i+1)<n&&str[i][j+2]=='^'&&str[i+1][j+1]=='v'&&!sign[i][j+2]&&!sign[i+1][j+1]){
                            sign[i][j+2] = 1;
                            sign[i+1][j+1] = 1;
                            sign[i][j] = 1;
                            count++;
                        }
                    }
                    else if(str[i][j]=='<'){
                        if((i+2)<n&&(j+1)<m&&str[i+1][j+1]=='>'&&str[i+2][j]=='<'&&!sign[i+1][j+1]&&!sign[i+2][j]){
                            sign[i][j]=1;
                            sign[i+1][j+1]=1;
                            sign[i+2][j] = 1;
                            count++;
                        }
                    }
                    else if(str[i][j]=='>'){
                        if((i+2)<n&&(j-1)>=0&&str[i+1][j-1]=='<'&&str[i+2][j]=='>'&&!sign[i+1][j-1]&&!sign[i+2][j]){
                            sign[i][j]=1;
                            sign[i+1][j-1] = 1;
                            sign[i+2][j] = 1;
                            count++;
                        }
                    }
                }
            }
            printf("%d
    ",count);
        }
        return 0;
    }
    
    

    E.千万别用树套树

    题意:

    维护一个区间的集合(相同元素可重复插入),有两种操作:

    1. 操作一(更新):1 L R
         在集合中插入一个线段[L,R]
    2. 操作二(询问):2 L R
        询问集合中满足条件的元素[x,y]的个数,x <= L <= R <= y
      (能完全盖住给定区间的线段的个数)
      题目保证L,R,N<=100,000
      数据保证询问的L,R 满足R - L <= 2,R<=n<=100,000

    思路:

    	ansLeft = num(x>=L+1) + num(y<=R-1) + (R-L==2)*mp[L+1]
    
    • 总的区间数 - 右端点小于R的区间 - 左端点大于L的区间 + 重复减去的就是答案。
    • 因为R-L<=2。当R=L 或R = L+1时,不会重复
    • 但R-1==L+1的时候,会重复减去左右区间均为L+1的区间数,我们用map维护左右端点相同的区间数即可
    • 然后相当于两颗线段树维护所有元素左端点的区间和,和右端点的区间和即可

    代码

    #include <bits/stdc++.h> 
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    using namespace std;
    const int maxn = 1e5 + 100;
    struct Node{
        //int left,right;省略不写
    	int sum[2];
    }tree[maxn<<2];
    void build(int left,int right,int pos=1)
    {
    	tree[pos].sum[0] = tree[pos].sum[1] = 0;
    	if(left==right) return;
    	int mid = (left+right)>>1;
    	build(left,mid,pos<<1);
    	build(mid+1,right,pos<<1|1);
    } 
    //Y_Cl风格
    int update1(int left,int right,int x,int id,int pos=1) //在区间tree[pos]:[left,right]区间内插入x 
    {
    	if(x>right||x<left) return tree[pos].sum[id];
    	if(left==right)
    	{
    		if(left==x) tree[pos].sum[id]++;
    		return tree[pos].sum[id];
    	}
    	int mid = (left+right)>>1;
    	int nL = update1(left,mid,x,id,pos<<1);
    	int nR = update1(mid+1,right,x,id,pos<<1|1);
    	return tree[pos].sum[id] = nL+nR;
    }
    //孙少风格,此处使用略快
    void update(int left,int right,int x,int id,int pos=1)
    {
    	if(left==right)
    	{
    		tree[pos].sum[id]++;
    		return;
    	}
    	int mid = (left+right)>>1;
    	if(x<=mid) update(left,mid,x,id,pos<<1);
    	else update(mid+1,right,x,id,pos<<1|1);
    	tree[pos].sum[id] = tree[pos<<1].sum[id]+tree[pos<<1|1].sum[id]; 
    }
    int query(int left,int right,int qx,int qy,int id,int pos=1)
    {	if(qx>right||qy<left)	return 0;	
    	if(qx<=left&&right<=qy) return tree[pos].sum[id];	 
    	int mid = (left+right)>>1;
    	int nL = query(left,mid,qx,qy,id,pos<<1);
    	int nR = query(mid+1,right,qx,qy,id,pos<<1|1);
    	return nL+nR;
    }
    int main()
    {
    	//freopen("in.txt","r",stdin);
       	//freopen("out.txt","w",stdout);
    	int n,q,L,R,t;
    	while(scanf("%d%d",&n,&q)!=EOF)
    	{
    		map<int,int> mp;
    		build(1,n);
    		int tot = 0;
    		while(q--)
    		{
    			scanf("%d%d%d",&t,&L,&R);
    			if(t==1)
    			{
    				update(1,n,L,0),update(1,n,R,1),++tot;
    				if(L==R) ++mp[L];	
    			} 
    			else 
    			{
    				int small = query(1,n,1,R-1,1); //询问y<=R-1的区间的个数 
    				int big   = query(1,n,L+1,n,0); //询问x>=L+1的区间的个数 
    				int add   = (L==R-2)*mp[L+1];
    				int ans   = tot - small - big + add;
    				printf("%d
    ",ans);
    			} 
    		}
    	}
    	return 0;
    }
    

    J.买一送一
    ps:补了题发现我的提交是三个队里面运行时间最短的(416ms)没luan用

    题面:

    ICPCCamp 有 n 个商店,用 1, 2, …, n 编号。对于任意 i > 1,有从商店 pi 到 i 的单向道路。 同时,商店 i 出售类型为 ai 的商品。
    
    Bobo 从商店 1 出发前往商店 i。他要在两个不同的商店购买商品(包括商店 1 和 i)。设他先购买的商品类型是 x,后购买的商品类型是 y,他用 fi 表示不同的有序对 ⟨x, y⟩ 的数量。 求出 f2, f3, …, fn 的值。
    
    1 ≤ n ≤ 105
    1 ≤ pi < i
    1 ≤ ai ≤ n
    n 的总和不超过 5 × 105.
    Input
    输入文件包含多组数据,请处理到文件结束。
    
    每组数据的第一行包含 1 个整数 n.
    
    第二行包含 (n − 1) 个整数 p2, p3, …, pn.
    
    第三行包含 n 个整数 a1, a2, …, an.
    
    Output
    对于每组数据输出 (n − 1) 个整数表示 f2, f3, …, fn.
    
    Sample Input
    3
    1 2
    1 2 3
    3
    1 1
    1 2 3
    4
    1 2 3
    1 3 2 3
    Sample Output
    1
    3
    1
    1
    1
    3
    5
    Hint
    对于第三个样例,当 i = 4 时,可能的有序对 ⟨x, y⟩ 有 ⟨1, 2⟩,⟨1, 3⟩,⟨2, 3⟩,⟨3, 2⟩,⟨3, 3⟩ 共 5 种。所以 f4 = 5.
    

    分析:
    一共有n个节点,n-1条有向边构成的一个图。

    • 它要么是一棵树,要么存在孤立的点和环,但是环的话,从起点1肯定是不可达的。所以我们从起点开始,dfs生成树就好了。
    • 题目求从起点到每个点,图中在不同的两个商店买两个物品组成的有序对(x,y)的个数。 那答案可定就在这个点到根节点的一条唯一确定的路上。
    • 可以从父节点递归过来,ans[now] = ans[fa[now]] + add
    • add就是以当前节点(商店)为y,以前面节点为x,且和父节点的所有有序对不重复的有序对(x,y)的数量
    • 那怎么保证不重复呢?
    •   如果这个点在这条dfs路径中是第一次出现,那么以它为y,肯定不会重复,那么add就等于前面所有商店出现的不同货物的种类。所以我们要维护一个numType数组表示从根节点到每个节点图中不同商品的种类数
        如果这个点的货物种类t在从根节点到它的这条dfs路径中已经出现过了,那么我们需要知道t最后出现的位置lastSeen。这样的话lastSeen之前的x都和t配过(x,t)这样的有序对了,lastSeen之后的,当前节点之前的货物种类就是add
    • 还有一个就是要考虑(t,t)正样x和y相同的有序对,如果之前出现t的次数>=2,那么(t,t)就已经出现过了,不让的话add++就好了
    • 我是和zyf一样用vector v[maxn]来按顺序存每种商品出现的位置(节点编号),往下递归时push_back(), 回溯时pop_back() 我看twt是用一个set维护的

    代码:

    /*
    Accepted 416ms 13276kB
    1739 C++ 2019-04-01 19:49:39
    */
    #include <bits/stdc++.h> 
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define LL long long
    #define MP make_pair
    #define pb push_back
    using namespace std;
    const int maxn = 1e5 + 20;
    int head[maxn],tot;
    struct Edge{ ///邻接表存边 
    	int to,Next;
    }edge[maxn];
    void initG(int n)
    {
    	memset(head,-1,sizeof(int)*(n+2));
    	tot = 0;
    }
    void addedge(int u,int v)
    {
    	edge[tot].to = v;
    	edge[tot].Next = head[u];
    	head[u] = tot++;
    }
    vector<int> pos[maxn+2]; ///按照dfs的顺序存储每种商品对应的商店号 
    int numType[maxn]; //存每个节点到根节点这条路中不同货物的数量 
    LL ans[maxn]; //存储节点对应的答案 
    int a[maxn]; //type of goods 存商店所卖货物的种类 
    void dfs(int fa,int now) 
    {
    	int lenth = 0;
    	if(now==1) //如果是根节点,直接往下dfs,ans和numType已经初始化 
    		goto Line;
    	numType[now] = numType[fa];
    	if(!pos[a[now]].size()) ///if this type of good haven't appeared, ans++ 
    	{
    		numType[now] += 1; ///如果前面没有出现过这种货物,对应的货物种类等于父节点+1 
    	}
    	lenth = pos[a[now]].size(); ///前面出现的同种货物的次数 
    	if(!lenth) //this type hasn't appeared before
    	{ //前面没有出现过这种货物 
    		ans[now] = ans[fa] + numType[fa];
    	}
    	else
    	{
    		int lastSeen = pos[a[now]][lenth-1];//the last pos(node) that this type appeared
    		ans[now] = ans[fa]+numType[fa]-numType[lastSeen];
    		if(lenth==1) ans[now]++; // 3 3 
    	}
    	Line:
    	pos[a[now]].push_back(now);
    	for(int i=head[now];i!=-1;i=edge[i].Next)
    	{
    		int to = edge[i].to;
    		dfs(now,to);	
    	} 
    	pos[a[now]].pop_back();	
    } 
    int main()
    {
    	int n,p;
    	while(scanf("%d",&n)!=EOF)
    	{
    		initG(n);
    		memset(ans,0,sizeof(int)*(n+2));
    		For(i,2,n)
    			scanf("%d",&p),addedge(p,i);
    		For(i,1,n)
    			scanf("%d",a+i);
    		ans[1] = 0;
    		numType[1] = 1;
    		dfs(1,1);
    		For(i,2,n)
    			printf("%lld
    ",ans[i]);
    	}
    	return 0;
    }
    

    K.Use FFT
    题意:
    A = a0 + a1*x^1 + a2 * x^2 + … + am * x^m
    B = b0 + b1*x^1 + b2 * x^2 + … + bn * x^n
    C = A * B
     = c0 + c1*x^1 + c2 * x^2 + … + c[m+n] *x^(m+n)
    多组询问,每组询问给出L,R(0<=L,R<=m+n)
    求c[L] + c[L+1] + … +c[R-1]+c[R]

    分析:
    就是a[i] * sumb[j] 求和,a from … to …
    见下面的例子:

    m = 2, n = 3
    C[0] = a[0] * b[0]
    C[1] = a[0] * b[1] + a[1] * b[0]
    C[2] = a[0] * b[2] + a[1] * b[1] + a[2] * b[0]
    C[3] = a[0] * b[3] + a[1] * b[2] + a[2] * b[1] + a[3] * b[0]
    C[4] = a[0] * b[4] + a[1] * b[3] + a[2] * b[2] + a[3] * b[1] + a[4] * b[0]
    C[5] = a[0] * b[5] + a[1] * b[4] + a[2] * b[3] + a[3] * b[2] + a[4] * b[1] + a[5] * b[0]
    
    C[0] = a[0] * b[0]
    C[1] = a[0] * b[1] + a[1] * b[0]
    C[2] = a[0] * b[2] + a[1] * b[1] + a[2] * b[0]
    C[3] = a[0] * b[3] + a[1] * b[2] + a[2] * b[1]
    C[4] =               a[1] * b[3] + a[2] * b[2]
    C[5] =                             a[2] * b[3]
    
    m = 3, n = 4
    C[0] = a[0] * b[0]
    C[1] = a[0] * b[1] + a[1] * b[0]
    C[2] = a[0] * b[2] + a[1] * b[1] + a[2] * b[0]
    C[3] = a[0] * b[3] + a[1] * b[2] + a[2] * b[1] + a[3] * b[0]
    C[4] = a[0] * b[4] + a[1] * b[3] + a[2] * b[2] + a[3] * b[1] + a[4] * b[0]
    C[5] = a[0] * b[5] + a[1] * b[4] + a[2] * b[3] + a[3] * b[2] + a[4] * b[1] + a[5] * b[0]
    C[6] = a[0] * b[6] + a[1] * b[5] + a[2] * b[4] + a[3] * b[3] + a[4] * b[2] + a[5] * b[1] + a[6] * b[0]
    C[7] = a[0] * b[7] + a[1] * b[6] + a[2] * b[5] + a[3] * b[4] + a[4] * b[3] + a[5] * b[2] + a[6] * b[1] + a[7] * b[0]
    
    C[0] = a[0] * b[0]
    C[1] = a[0] * b[1] + a[1] * b[0]
    C[2] = a[0] * b[2] + a[1] * b[1] + a[2] * b[0]
    C[3] = a[0] * b[3] + a[1] * b[2] + a[2] * b[1] + a[3] * b[0]
    C[4] = a[0] * b[4] + a[1] * b[3] + a[2] * b[2] + a[3] * b[1]
    C[5] =               a[1] * b[4] + a[2] * b[3] + a[3] * b[2]
    C[6] =                             a[2] * b[4] + a[3] * b[3]
    C[7] =                                           a[3] * b[4]
    
    

    是不是一目了然?^_^

    代码:

    //by xzc
    #include <bits/stdc++.h> 
    #define Mst(a,b) memset(a,(b),sizeof(a))
    #define For(i,a,b) for(register int i=(a);i<=(b);++i)
    #define LL long long
    #define MP make_pair
    #define pb push_back
    using namespace std;
    const int maxn = 5e5 + 10;
    const LL mod = 1e9+7;
    LL a[maxn],b[maxn],sumb[maxn];
    int m,n;
    LL gb(int i)
    {
    	if(i<0) return 0;
    	if(i>n) return sumb[n];
    	return sumb[i];
    }
    LL S(int left,int right)
    {
    	return (gb(right)-gb(left-1)+mod)%mod;	
    } 
    int main()
    {
    	//freopen("in.txt","r",stdin);
       	//freopen("out.txt","w",stdout);
    	int L,R;
    	while(scanf("%d%d%d%d",&m,&n,&L,&R)!=EOF)
    	{
    		For(i,0,m) scanf("%lld",a+i);
    		For(i,0,n) scanf("%lld",b+i);
    		sumb[0] = b[0];	 
    		For(i,1,n) sumb[i] = (sumb[i-1]+b[i])%mod;
    		LL ans = 0;
    		int right = min(R,m); 
    		For(i,0,right)
    			ans = (ans+a[i]*S(max(0,L-i),R-i)%mod) % mod;
    		printf("%lld
    ",ans);	
    	} 
    	return 0;
    }
    
    //by lj
    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int mod = 1e9+7;
    const int N = 5e5+10;
    long long a[N],b[N];
    long long sum[N];
    int main(){
        int n,m,l,r,mini,maxe;
        long long ans;
        while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF){
            ans = 0;
            for(int i = 0;i <= n;i++) scanf("%lld",&a[i]);
            for(int i = 0;i <= m;i++){
                scanf("%d",&b[i]);
                if(i==0) sum[i] = b[i];
                else sum[i] = sum[i-1]+b[i];
                sum[i] = sum[i]%mod;
            }
            for(int i = m+1;i<=m+n;i++) sum[i] = sum[i-1];
    
            for(int i = 0;i <= r;i++){
                if(i>n) break;
                if(l-i-1<0) ans += sum[r-i]*a[i]%mod;
                else ans+=(sum[r-i]-sum[l-i-1]+mod)%mod*a[i]%mod;
                ans = ans%mod;
            }
           printf("%lld
    ",ans);
        }
    }
    

  • 相关阅读:
    1010考试T1
    P5631 最小mex生成树 分治 并查集
    P4366 [Code+#4]最短路 建图 最短路
    P1654 OSU! 期望概率DP
    7.26集训
    7.25集训
    7.23集训
    7.22集训
    7.21test
    7.12test
  • 原文地址:https://www.cnblogs.com/Apare-xzc/p/12243675.html
Copyright © 2011-2022 走看看