【分块】【双端队列】Day4 - C

链接

C

题目描述

在这里插入图片描述

思路

分块维护不同个数的值,每一块用双端队列去维护轮转
是KouA了啊,因为不是很会实现

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

int A[335][100005], B[100005], C[355], D[355], num, cnt, n, m;

int read() 
{
    
    
	int x = 0, flag = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {
    
    if (ch == '-') flag = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9'){
    
    x = x * 10 + ch - '0'; ch = getchar();}
	return x * flag;
}

deque <int>Q[100005];
 
int main()
{
    
    
	n = read(); m = read();
	num = sqrt(n);
	for(int i = 1; i <= n; ++i) 
	{
    
    
		 int x; x = read();
		 if(i  > num * cnt) ++cnt;
		 Q[cnt].push_back(x);
		 B[i] = cnt, ++A[cnt][x];
	}
	while(m--)
	{
    
    
		int opt; opt = read();
		if(opt == 1)
		 {
    
    
			int l, r; l = read(); r = read();
			if(B[l] == B[r])
			{
    
    
				int G = B[l];
				l = l % num; if(l == 0) l = num;
				r = r % num; if(r == 0) r = num;
			    for(int i = 1; i < l; ++i) 
				    C[i] = Q[G].front(), Q[G].pop_front();
			    for(int i = 1; i <= num - r; ++i)
			        D[i] = Q[G].back(), Q[G].pop_back();
			        
			    int x = Q[G].back(); Q[G].pop_back(); Q[G].push_front(x); 
				for(int i = l - 1; i >= 1; --i) Q[G].push_front(C[i]);
			    for(int i = 1; i <= num - r; ++i) Q[G].push_back(D[(num - r) - i + 1]);
			}
			else 
			{
    
    
				int G = B[l], k = l; while(B[k + 1] == G) k++;
			    int len1 = k - l + 1;
			    for(int i = 1; i <= len1; ++i)
				    C[len1 - i + 1] = Q[G].back(), Q[G].pop_back(), A[G][C[len1 - i + 1]]--; 
				    
			    int F = B[r], h = r; while(B[h - 1] == F) h--;
			    int len2 = r - h + 1; 
			    for(int i = 1; i <= len2; ++i)
			        D[i] = Q[F].front(), Q[F].pop_front(), A[F][D[i]]--;
			    
			    Q[G].push_back(D[len2]), A[G][D[len2]]++;
			    for(int i = 1; i < len1; ++i) Q[G].push_back(C[i]), A[G][C[i]]++;
	            
	            for(int i = len2 - 1; i >= 1; --i) Q[F].push_front(D[i]), A[F][D[i]]++; 
				int x = Q[F - 1].back(); if(F == G + 1) x = C[len1];
				Q[F].push_front(x), A[F][x]++;
	            
	            int last = C[len1];
	            for(int i = G + 1; i <= F - 1; ++i)
	            {
    
    
				    Q[i].push_front(last); A[i][last]++;
					last = Q[i].back(); Q[i].pop_back();
					A[i][last]--; 	    
			    }
			}
		} 
		else 
		{
    
    
			int l, r, K, ans = 0; l = read(); r = read(); K = read();
			if(B[l] == B[r])
			{
    
    
				int G = B[l];
				l = l % num; if(l == 0) l = num;
				r = r % num; if(r == 0) r = num;
			    for(int i = 1; i < l; ++i) 
				    C[i] = Q[G].front(), Q[G].pop_front();
			    for(int i = 1; i <= num - r; ++i)
			        D[i] = Q[G].back(), Q[G].pop_back();
			        
				for(int i = l - 1; i >= 1; --i) 
				{
    
    
					if(C[i] == K) ans++;
				    Q[G].push_front(C[i]);
				}
			    for(int i = 1; i <= num - r; ++i) 
				{
    
    
				    if(D[(num - r) - i + 1] == K) ans++;
					Q[G].push_back(D[(num - r) - i + 1]);
			    }
			    ans = A[G][K] - ans;
			}
			else 
			{
    
    
				int G = B[l], k = l; 
				while(B[k + 1] == G) ++k;
			    int len1 = k - l + 1;
			    for(int i = 1; i <= len1; ++i)
					C[len1 - i + 1] = Q[G].back(), Q[G].pop_back(); 
				for(int i = 1; i <= len1; ++i) 
				{
    
    
				    if(C[i] == K) ans++;
					Q[G].push_back(C[i]);
				}
				
			    int F = B[r], h = r; 
				while(B[h - 1] == F) h--;
			    int len2 = r - h + 1; 
			    for(int i = 1; i <= len2; ++i) 
					D[i] = Q[F].front(), Q[F].pop_front();  
	            for(int i = len2; i >= 1; --i) 
				{
    
    
				    if(D[i] == K) ans++;
					Q[F].push_front(D[i]); 
			    }
	            for(int i = G + 1; i <= F - 1; ++i) ans += A[i][K];
			} 
			printf("%d\n", ans);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/119652272