1 条题解

  • 0
    @ 2025-8-24 22:20:02

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 7KByte
    **

    搬运于2025-08-24 22:20:02,当前版本为作者最后更新于2021-07-20 17:40:37,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


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

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

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

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

    时间复杂度 O(N2+NQ)\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;
    }
    
    
    • 1

    信息

    ID
    5383
    时间
    1500ms
    内存
    32MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者