1 条题解

  • 0
    @ 2024-8-30 21:19:46
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 5;
    int n, m, q, p[maxn], nxt[maxn], a[maxn], f[maxn][20], pos[maxn], g[maxn]; 
    // nxt[x]表示排列中数值为x的数的下一个位置的数 
    // pos[x] 对于当前 a[i] 来说,a[i] 后面出现的数值为 x 的数里面的最小下标 a[j]==x 且 j 最小 
    
    int st[maxn][20]; // s[i][j] 表示 g[i] 开始的连续 2^j 个数的最小值
    void build_st() {	// 建立ST表 
    	for (int j = 0; j <= 19; j++) {
    		for (int i = 1; i+(1<<j)-1 <= m; i++) {
    			if (j == 0) 
    				st[i][j] = g[i];
    			else
    				st[i][j] = min(st[i][j-1], st[i+(1<<j-1)][j-1]);
    		}
    	}
    }
    int query_min(int l, int r) {	// 查询 g[l..r] 的最小值 
    	int len = log2(r - l + 1);
    	return min(st[l][len], st[r-(1<<len)+1][len]);
    }
    
    int main() {
    	scanf("%d%d%d", &n, &m, &q);
    	for (int i = 0; i < n; i++)
    		scanf("%d", p+i);
    	for (int i = 0; i < n; i++)
    		nxt[p[i]] = p[(i+1)%n];
    	for (int i = 1; i <= m; i++)
    		scanf("%d", a+i);
    	fill(pos+1, pos+n+1, m+1);	// 把 pos[1..n] 都填充为 m+1
    //	f[m+1][0] = m+1;	f[m+1][0..19] = m+1;
    	fill(f[m+1], f[m+1]+20, m+1);
    	for (int i = m; i >= 1; i--) {
    		int x = nxt[a[i]]; // x : a[i] 在排列 p 中的下一个位置的数值 
    		f[i][0] = pos[x];
    		pos[a[i]] = i;
    	}
    	for (int j = 1; j <= 19; j++)
    		for (int i = 1; i <= m; i++)
    			f[i][j] = f[f[i][j-1]][j-1];
    	for (int i = 1; i <= m; i++) { // 求 g[i] 
    		int u = i;
    		for (int j = 0; j <= 19; j++)
    			if (((n-1)>>j) & 1)
    				u = f[u][j];
    		g[i] = u;
    	}
    //	for (int i = 1; i <= m; i++)
    //		printf("g[%d] = %d\n", i, g[i]);
    	build_st();
    	while (q--) {
    		int l, r;
    		scanf("%d%d", &l, &r);
    		printf(query_min(l, r) <= r ? "1" : "0");
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    7
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    8
    已通过
    3
    上传者