码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #326 (Div. 1) B - Duff in Beach

时间:2020-07-07 18:02:23      阅读:34      评论:0      收藏:0      [点我收藏+]

标签:多少   line   return   div   while   来源   tchar   double   长度   

首先我们可以发现,长度为l的数组就是a数组不断循环构成。
令dp[i][j]表示操作到第j块,结尾是第i个数字时的结果。
\(dp[i][j]=\sum_{k=0}^{n-1}dp[k][j-1]\)但是这样复杂度过高。
于是,我们考虑前\(n\cdot k\)个数字。
在第j块中的第i个数字,其实转移,只有他前面的所有比他小的数字,我们考虑sort出前面n*k个数字的大小。从小到大遍历。
令f[i]表示第i个数字的贡献,\(sum[i]\)表示第i个块的贡献。
我们的\(f[i]=sum[\frac{i}{n}-1]\),表示第i个数字的贡献,来源于前面一个块,所以比他小的数字,即我们把第一个数字的\(\sum\)给变成sum,并且大小排序通过sort来实现。更新\(sum[i]+=f[i]\)即可。
紧接着考虑对ans的贡献,\(f[i]\)对ans的贡献=\((\frac{l-pos-1}{n}+1)\cdot f[i]\)
前面表示l到pos有多少个n在里面(因为是a数组不断滚动),然后加1(自己)。这样的话,就能表示长度为\(i\div n\),以\(a[i]\)结尾,的所以贡献值。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
	while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int mod = 1000000007;
const int N = 1e6 + 10;
ll n, l, k;
ll a[N];
struct node {
	ll a, b;
	bool operator<(const node temp)const 
	{
		if (a == temp.a)
			return b < temp.b;
		else return a < temp.a;
	}
};
ll sum[N]; ll dp[N];
int main()
{
	n = read(), l = read(), k = read();
	vector<node>vec(n*k);
	up(i, 0, n)
	{
		a[i] = read();
		vec[i] = node{ a[i],i };
	}
	up(i, n, n*k)
	{
		a[i] = a[i%n];
		vec[i] = node{ a[i],i };
	}	
	sort(vec.begin(), vec.end());
	ll ans = 0;
	up(i, 0, n*k)
	{
		ll temp = vec[i].a;
		ll pos = vec[i].b;
		if (pos < n)dp[pos] = 1;
		else dp[pos] = sum[pos / n - 1];
		sum[pos / n] += dp[pos];
		sum[pos / n] %= mod;
		ll dis = (l - pos - 1) / n + 1;
		dis %= mod;
		if (pos < l)
			ans = (ans + (dp[pos] * dis % mod)) % mod;
	}
	cout << ans << endl;
	return 0;
}

Codeforces Round #326 (Div. 1) B - Duff in Beach

标签:多少   line   return   div   while   来源   tchar   double   长度   

原文地址:https://www.cnblogs.com/LORDXX/p/13261903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!