Loading

【题解】[CEOI2018]Lottery

考虑到 \(N\le 10^4\) ,显然是 \(\mathcal{O}(N^2)\) 可过。

所以我们可以直接枚举两个区间计算贡献。

显然如果我们知道两两区间的距离,可以直接前缀和 \(\mathcal{O}(NQ)\) 求出最终答案。

现在我们计算两两区间的距离,直接枚举并匹配是 \(\mathcal{O}(N^3)\) ,但是不难发现 \(([l_1, r_1], [l_2, r_2])\)\(([l_1+1, r_1+1], [l_2 + 1, r_2 + 1])\) 只有头尾两位不同,我们枚举 \(l_1\),和差 \(l_2 - l_1\),然后可以递推出所有结果。

时间复杂度 \(\mathcal{O}(N^2+NQ)\)

/*
    Author : SharpnessV
    Right Output ! & Accepted !
*/
#include<bits/stdc++.h>
//#define int long long

#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define pre(i, a, b) for(int i = (a);i >= (b);i--)
#define rp(i, a) for(int i = 1; i <= (a); i++)
#define pr(i, a) for(int i = (a); i >= 1; i--)
#define go(i, x) for(auto i : x)

#define mp make_pair
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define ze(p) memset(p, 0, sizeof(p))
#define mem(p, x) memset(p, x, sizeof(p))
#define YES puts("YES")
#define NO puts("NO")
#define si(x) (int)(x).size()
#define db cerr
#define pc putchar
#define el putchar('\n')

using namespace std;
const double eps = 1e-15, pi = 3.1415926535897932385;
typedef long long LL;
typedef pair<int,int> Pr;
const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1}, inf = 0x7fffffff;

//char buf[1<<22],*p1=buf,*p2=buf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read(){
    int x = 0;bool f = 1;char ch = getchar();
    while(!isdigit(ch))f = ('-' == ch ? 0 : 1), ch = getchar();
    while(isdigit(ch))x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    if(f)return x;return -x;
}
inline LL Read(){
    LL x = 0;bool f = 1;char ch = getchar();
    while(!isdigit(ch))f = ('-' == ch ? 0 : 1), ch = getchar();
    while(isdigit(ch))x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    if(f)return x;return -x;
}
int gcd(int x,int y){return y ? gcd(y, x % y) : x;}
int lcm(int x,int y){return x / gcd(x, y) * y;}
#define P 1000000007
//#define P 998244353
#define bas 229
inline void ad(int &x, int y){x += y; if(x >= P) x -= P;}
inline void su(int &x, int y){x -= y; if(x < 0) x += P;}
inline void cmn(int &x,int y){if(y < x) x = y;}
inline void cmx(int &x,int y){if(y > x) x = y;}

int Pow(int x, int y){
	if(y < 0)return Pow(Pow(x, P - 2), -y);
	int now = 1 ;
	for(;y;y >>= 1, x = 1LL * x * x % P)if(y & 1) now = 1LL * now * x % P;
	return now;
}
#define N 10005
int n, m, l, a[N], ans[102][N], k[N], mat[N], w[N];
int main(){
	//int T = read();while(T--)solve();
	//freopen("INPUT","r",stdin);
	n = read(), l = read();
	rp(i, n)a[i] = read();
	m = read();
	rp(i, m)w[i] = k[i] = read();
	sort(k + 1, k + m + 1);
	rp(i, m)mat[k[i]] = i;
	mat[l + 1] = m + 1;pre(i, l, 0)if(!mat[i])mat[i] = mat[i + 1];
	//rep(i, 0, l)printf("%d ",mat[i]);el;
	rep(i, 1, n - l){
		int sum = 0;
		rep(j, 0, l - 1)sum += a[1 + j + i] != a[1 + j];
		//cout<<"ss "<<i + 1<<" "<<sum<<endl;
		rep(j, 0, n - l - i){
			ans[mat[sum]][1 + j]++, ans[mat[sum]][i + j + 1] ++;
			sum -= a[1 + j] != a[1 + i + j];
			sum += a[j + l + 1] != a[i + j + l + 1];
		} 
	}
	rp(i, m)rp(j, n - l + 1)ans[i][j] += ans[i - 1][j];
	rp(i, m){rp(j, n - l + 1)printf("%d ",ans[mat[w[i]]][j]);el;}
	return 0;
}

posted @ 2021-10-04 16:50  7KByte  阅读(71)  评论(0编辑  收藏  举报