首页 > 其他分享 >Codeforces 587D Duff in Beach

Codeforces 587D Duff in Beach

时间:2024-02-25 20:44:47浏览次数:26  
标签:结尾 587D int Codeforces i64 maxn 长度 Beach mod

不难发现可以按长度为 \(n\) 分为段。

考虑到 \(l\) 其实并没什么大用,只是说对于选出来的 \(b_{1\sim x}\) 可以都整体移任意段,只需要保证在范围内就行了。
进一步的,发现只需要看最后一个数的取值得到其最大可以在的段数即为 \(d\),那么移动的方案数就为 \(d - x + 1\)。

还有的一部分是计数长度为 \(x\) 的以 \(a_i\) 结尾的序列的方案数。
令 \(f_i\) 为长度为 \(x\) 以 \(a_i\) 结尾的方案数,\(f'_i\) 为长度为 \(x - 1\) 以 \(a_i\) 结尾的方案数。
转移式 \(f_i = \sum\limits_{j = 1}^n [a_i\ge a_j]f'_j\)。
能发现这即是一个前缀和的形式,考虑离散化值域处理。

时间复杂度 \(O(n\log n + nk)\)。

#include<bits/stdc++.h>
using i64 = long long;
const i64 mod = 1e9 + 7;
const int maxn = 1e6 + 10;
i64 a[maxn], b[maxn], f[maxn], g[maxn];
int main() {
    int n, k; i64 l; scanf("%d%lld%d", &n, &l, &k);
    i64 B = l / n - (l % n == 0); int s = l - B * n;
    for (int i = 1; i <= n; i++) scanf("%lld", &a[i]), b[i] = a[i];
    std::sort(b + 1, b + n + 1);
    for (int i = 1; i <= n; i++) a[i] = std::lower_bound(b + 1, b + n + 1, a[i]) - b;
    i64 ans = 0;
    for (int len = 1; len <= k; len++) {
        for (int i = 0; i <= n; i++) g[i] = 0;
        for (int i = 1; i <= n; i++) (g[a[i]] += f[i]) %= mod;
        g[0] = len == 1;
        for (int i = 1; i <= n; i++) (g[i] += g[i - 1]) %= mod;
        for (int i = 1; i <= n; i++) f[i] = g[a[i]];
        for (int i = 1; i <= n; i++) {
            i64 d = B + (i <= s);
            d >= len && ((ans += (d - len + 1) % mod * f[i]) %= mod);
        }
    }
    printf("%lld\n", ans);
    return 0;
}

标签:结尾,587D,int,Codeforces,i64,maxn,长度,Beach,mod
From: https://www.cnblogs.com/rizynvu/p/18032992

相关文章

  • Codeforces Round 926 (Div. 2)
    A.升序排列再求和#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;#defineinf0x3f3f3f3fvoidsolve(){intn;cin>>n;vector<int>a(n+1);for(inti=1;i<=n;i++)cin>>a[i];sort(a.b......
  • Educational Codeforces Round 162 (Rated for Div. 2)
    EducationalCodeforcesRound162(RatedforDiv.2)A-MovingChips解题思路:模拟一下,不难发现是\(1\)之间\(0\)的个数。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusin......
  • Codeforces 1025F Disjoint Triangles
    结论:如果两个三角形不相交,那么一定存在两条内公切线。于是可以考虑枚举这条内公切线的端点\(x,y\)。那么一个三角形的两个端点就会在\(x\toy\)这条线的同一侧,另外一个三角形的两个端点会在这条线的另一侧。同时这条线的一侧与其配对的端点可能是\(x\)也可能是\(y\)。......
  • Codeforces 486E LIS of Sequence
    考虑一个暴力的做法:建立一个超级起点\(a_0=0\)超级终点\(a_{n+1}=\inf\)。求出\(f_i\)代表\(1\simi\)且以\(i\)结尾的\(\text{LIS}\)长度。考虑\(f_i=\max\{f_j+1\}(j<i\landa_j<a_i)\)这个转移的式子,如果\(f_i=f_j+1(j<i\landa_j<a_i......
  • codeforces 1575M Managing Telephone Poles
    假设固定了\((x,y)\),考虑其和\((x',y')\)的距离\((x-x')^2+(y-y')^2=x^2-2xx'+x'^2+y^2-2yy'+y'^2=(x^2+y^2)+(-2xx'+x'^2)+(-2yy'+y'^2)\)。第一个括号内的式子是个定值,不用管;第二三个式子都是一次函数的形式......
  • Educational Codeforces Round 162 (Rated for Div. 2)
    不会F的场。A答案是最左的\(1\)和最右的\(1\)之间的\(0\)的个数。Code#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;intmain(){ ios::sync_with_stdio(false); cin.tie(0); intt; cin>>t; while(t--){ intn; cin>>n......
  • Educational Codeforces Round 162 [Rated for Div. 2]
    第二次,三道题,剩下的回学校再补,总结:还是需要多练习A:让数列里所有的1都挨在一起,可以看出,相邻1之间有多少个0就需要操作几次,特判:当只有一个1或者原本全是1就输出0;voidsolve(){cin>>n;inttop1=0,top2=0,cnt=0;memset(a,0,sizeof(a));memset(b,0,siz......
  • Codeforces 799E Aquarium decoration
    考虑去枚举能满足\(1,2\)的个数\(l\),那自然只能满足\(1\)或\(2\)的个数为\(\max\{k-l,0\}\)。对于还剩下的,可以从只能满足\(1,2\)和不能满足任意一个的选出来。显然如果要选就是选最小的。考虑用个数据结构优化这个过程。查询前\(k\)大的和,插入一个数,可以想......
  • Codeforces 图论题
    CF243BHydra枚举点\(u,v\),或者说枚举边。然后找出\(u,v\)分别所连的点。有数组\(st\),结点\(x\)仅与\(u\)相邻则\(st[x]=1\),仅与\(v\)相邻则\(st[x]=2\),与两个点都相邻则\(st[x]=3\)。用数组\(rest\)记录\(st[x]=3\)的所有\(x\)。先优先选走至多\(h\)个\(......
  • Codeforces 869D The Overdosing Ubiquity
    考虑树的\(\text{dfs}\)(根据当前节点\(u\)找到\(v\)满足存在\((u,v)\),然后走向\(v\)进入更深的搜索)为和能做到\(O(n)\)的复杂度。原因是没有环的情况,到每个点只有一条路径。回到这个题,有\(m\)条边导致到每个点可能有多条路径了。能发现其实还是能\(\text{dfs}\)......