• 【随缘更(gu)】牛客D4简要思路(没有题解)


    T1

    当然不能枚举每个区间,于是我们考虑算贡献。

    对于每个位置i,我们计算其作为区间内第一个出现ai的位置的区间总数,则有ans=sigma( i - last[i] ) * ( n - i + 1 ) ,n为区间长度,last[i]为上一个出现ai的位置。

    (其实还有一种简单的递推思路,定义f[i]为前 i 个数的权值和,f[i] = fi[-1] + i - last[i] ,可是我太菜了,没想清楚以为是错的Orz)

    这样我们解决了k=1的情况。

    然后我们考虑k不等于1

    如果我们复制第一段区间插在后面,定义第一段区间的权值和为C1,前两段为C2,则第二段对这两段的贡献delta=C2-C1,而且显然 第三段对第二、三两段的贡献也为delta,后面的同理。

    这样我们解决了相邻复读区间的贡献。

    对于不相邻的复读区间,由于跨一整个区间,则每个区间的权值都为tot,计算这些区间的总数即可。

    代码:

    #include <cstdio>
    #include <map>
    #include <iostream>
     
    #define int long long int
     
    using namespace std;
     
    const int mod=1e9+7;
     
    inline int read() {
        int x=0,f=1;
        char cr=getchar();
        while (cr>'9' || cr<'0') {
            if (cr=='-') f=-1;
            cr=getchar();
        }
        while (cr>='0' && cr<='9') {
            x=(x<<3)+(x<<1)+cr-'0';
            cr=getchar();
        }
        return x*f;
    }
     
    const int maxn=1000500;
     
    map<int,int> loc;
     
    int a[maxn],last[maxn];
     
    inline int sigma(int k) {
    	int x=k,y=k+1;
    	if (x&1) return (y/2*x)%mod;
    	return (x/2*y)%mod;
    }
    signed main() {
        int n=read(),k=read();
        int tot=0;
        for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++) {
    		if (!loc[a[i]]) tot++;
    		last[i]=loc[a[i]],loc[a[i]]=i;
    	}
    	if (k==1) {
    	    int ans=0;
    		for (int i=1;i<=n;i++) ans+=(i-last[i])*(n-i+1),ans%=mod;
    	    printf("%lld",ans);
    	    return 0;
    	}
    	else {
    		int cont1=0,cont2=0;
    		for (int i=1;i<=n;i++) cont1+=(i-last[i])*(n-i+1),cont1%=mod;
    		for (int i=n+1;i<=2*n;i++) a[i]=a[i-n],last[i]=loc[a[i]],loc[a[i]]=i;
    		for (int i=1;i<=2*n;i++) cont2+=(i-last[i])*(2*n-i+1),cont2%=mod;
    		int delt=cont2-cont1+mod;delt%=mod;
    		int ans=cont2;
    		ans+=(k-2)*(delt),ans%=mod;
    		ans+=(sigma(k-2)*n%mod*n%mod*tot%mod)%mod,ans%=mod;
    	    printf("%lld",ans);
    	    return 0;
    	}
    }
    

      

  • 相关阅读:
    The Zen of Python —— Python 之禅
    单片机最小系统
    处理器是如何驱动外设的
    嵌入式系统、开发板概念
    Xilinx Zynq ZC-702 开发(02)—— 通过 Xilinx SDK 调试 Linux 应用
    Linux 总线、设备、驱动模型 与 设备树
    Xilinx Zynq ZC-702 开发(01)—— 概览
    DLL 函数中使用结构体指针作函数参数(C# 调用 C++ 的 DLL)
    新装 Win7 系统装完驱动精灵,一打开到检测界面就卡死——原因与解决方案
    WPF 主窗口关闭时结束所有相关线程
  • 原文地址:https://www.cnblogs.com/YoOXiii/p/11804464.html
Copyright © 2020-2023  润新知