随笔- 22  文章- 0  评论- 10  阅读- 1579 

2022-9-26

T1

扩散

明显可以二分答案,也可以用最小生成树去做。考试时写的最小生成树,每两个点连一条边权为这两个点的曼哈顿距离。每次找最小的距离,÷2+1后更新ans(因为两个点都会扩散)

代码

#include<bits/stdc++.h>
#define MAXN 60
#define int long long
using namespace std;
int n,tot=0,ans=0;
int father[MAXN];
int fa(int data)
{
    if(father[data]==data)return data;
    return father[data]=fa(father[data]);
}
struct point
{
    int x,y;
}p[MAXN];
struct edge
{
    int l,r,w;
}ed[3000];
bool cmp(const edge a,const edge b)
{
    return a.w<b.w;
}
signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&p[i].x,&p[i].y);
        father[i]=i;
        for(int j=1;j<i;j++)
        {
            ed[++tot].l=j;
            ed[tot].r=i;
            ed[tot].w=abs(p[i].x-p[j].x)+abs(p[i].y-p[j].y)-1;
        }
    }
    sort(ed+1,ed+tot+1,cmp);
    int cnt=0;
    for(int i=1;i<=tot;i++)
    {
        if(fa(ed[i].l)==fa(ed[i].r))continue;
        father[fa(ed[i].l)]=father[fa(ed[i].r)];
        ans=max(ans,ed[i].w/2+1);
        cnt++;
        if(cnt==n-1)break;
    }
    printf("%lld",ans);
    return 0;
}

T2

树的统计

树链剖分模板题,不多赘述。

T3

佳佳的Fibonacci

问题描述:

佳佳对数学,尤其对数列十分感兴趣。在研究完 Fibonacci 数列后,他创造出许多稀奇古怪的数列。例如用S(n)表示 Fibonaccin项和 mod m 的值,即S(n)=(F1+F2++Fn)mod m,其中 F1=F2=1Fi=Fi1+Fi2。可这对佳佳来说还是小菜一碟。终于,她找到了一个自己解决不了的问题。用T(n)=(F1+2F2+3F3++nFn)mod m 表示 Fibonacci 数列前n项变形后的和 mod m 的值。现在佳佳告诉你了一个nm,请求出T(n)的值。

输入格式

共一行,包含两个整数 nm

输出格式

共一行,输出 T(n) 的值。

数据范围

1 ≤ nm2311

思路:

看题目已经给出了递推式,数据范围很大,考虑矩阵加速递推。

易得递推式为Ti=Ti1+iFi

注意到这个递推式有点特殊,包含nFn的乘积项。如果普通地把nFn放到状态矩阵中,不管怎么设计转移矩阵都不会产生乘积项。因此我们可以把乘积项nFn也放入矩阵中。
如何转移 nFn ? 推导思路如下:

(i+1)Fi+1=iFi+1+Fi+1=i(Fi+Fi1)+Fi1+Fi=iFi+iFi1+Fi1+Fi=iFi+(i1)Fi1+Fi1+Fi1+Fi=iFi+(i1)Fi1+2Fi1+Fi

因此我们需要记录iFi(i1)Fi1Fi1Fi,再加上Ti15个信息。
状态矩阵为

[Ti1FiFi1iFi(i1)Fi1]

它要转移到

[TiFi+1Fi(i+1)Fi+1iFi]

可得转移矩阵为

[1000001110010201001100010]

状态矩阵初始化为[01010],快速幂求n次方即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,mod;
struct matrix
{
    int mat[10][10],n,m;
    matrix(int a,int b)
    {
        n=a,m=b;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                mat[i][j]=0;
    }
    void set_i()
    {
        for(int i=1;i<=n;i++)
            mat[i][i]=1;
    }
    matrix operator *(matrix b)
    {
        matrix ans(n,b.m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=b.m;j++)
                for(int k=1;k<=m;k++)
                    ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*b.mat[k][j]%mod)%mod;
        return ans;
    }
};
matrix qpow(matrix a,int b)
{
    matrix ans(a.n,a.m);
    ans.set_i();
    while(b)
    {
        if(b&1)ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
signed main()
{
    scanf("%lld%lld",&n,&mod);
    matrix st(1,5);
    st.mat[1][1]=0;st.mat[1][3]=st.mat[1][5]=0;
    st.mat[1][2]=st.mat[1][4]=1;
    matrix a(5,5);
    a.mat[1][1]=a.mat[2][2]=a.mat[2][3]=a.mat[2][4]=a.mat[3][2]=a.mat[4][1]=a.mat[4][4]=a.mat[4][5]=a.mat[5][4]=1;
    a.mat[3][4]=2;

    st=st*qpow(a,n);
    printf("%lld",st.mat[1][1]%mod);
    return 0;
}

T4

[CQOI2009]中位数

题目描述

给出 1,2,...,n 的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是 b。中位数是指把所有元素从小到大排列后,位于中间的数。

输入格式

第一行为两个正整数 nb,第二行为 1,2,...,n 的排列。

输出格式

输出一个整数,即中位数为 b 的连续子序列个数。

提示

对于 30% 的数据中,满足 n100

对于 60% 的数据中,满足 n1000

对于 100% 的数据中,满足 n100000,1bn

思路

把数组中比 b 大的数设为 1 ,比 b 小的数设为 1 ,这样如果 b 为一段连续子序列的中位数,那么这段子序列除 b 外其他数的和一定为0。因此我们先从 b 所在的位置开始往左边扫一遍,在扫的过程中累加元素的值,并开一个 map 存有多少个节点到 b 的和是这个值。再从 b+1 开始从左往右扫,跟第一遍一样累加,每累加一个节点就ans+=map[sum],最后得到答案。

代码

#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
int n,b,pos,a[MAXN],ans=0,sum=0;
map<int,int> mp;
int main()
{
	scanf("%d%d",&n,&b);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		if(a[i]==b)pos=i;
		else if(a[i]<b)a[i]=-1;
		else a[i]=1;
	}
	for(int i=pos-1;i>=1;i--)
	{
		sum+=a[i];
		if(sum==0)ans++;
		mp[sum]++;
	}
	sum=0;
	for(int i=pos+1;i<=n;i++)
	{
		sum+=a[i];
		if(sum==0)ans++;
		ans+=mp[0-sum];
	}
	printf("%d",++ans);
    return 0;
}
 posted on   hu_led  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示