QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#522970#5047. PermutationJEdwardWA 53ms17920kbC++175.5kb2024-08-17 17:37:132024-08-17 17:37:14

Judging History

你现在查看的是最新测评结果

  • [2024-08-17 17:37:14]
  • 评测
  • 测评结果:WA
  • 用时:53ms
  • 内存:17920kb
  • [2024-08-17 17:37:13]
  • 提交

answer

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0)
#define int long long
#define endl '\n'
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define pb push_back
#define all(s) s.begin(), s.end()
#define ls(x) (x<<1)
#define rs(x) (x<<1|1) 
#define here system("pause")
using namespace std;
template <class T> inline void read(T& x) { x = 0; char c = getchar(); bool f = 0; for (; !isdigit(c); c = getchar()) f ^= (c == '-'); for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); x = f ? -x : x; }
template <class T> inline void write(T x) { if (x < 0) putchar('-'), x = -x; if (x < 10) putchar(x + 48); else write(x / 10), putchar(x % 10 + 48); }
template<typename T> void chkmin(T& lhs, const T& rhs) { lhs = lhs > rhs ? rhs : lhs; }
template<typename T> void chkmax(T& lhs, const T& rhs) { lhs = lhs < rhs ? rhs : lhs; }

const int N = 5e5+5;
const int mod = 998244353;
const int INF = 1e18+7;
const double eps = 1e-6;
inline int pow(int a, int b, int p){ int res = 1%p; while(b){ if(b&1) res=res*a%p; a=a*a%p, b>>=1;} return res;}
inline int inv(int a, int p){ return pow(a,p-2,p)%p;}
mt19937 rnd(chrono::duration_cast< chrono::nanoseconds>(chrono::system_clock::now().time_since_epoch()).count());
inline int randint(int L, int R) {
	uniform_int_distribution<int> dist(L, R);
	return dist(rnd);
}
//#define LOCAL

int n, c;
int a[N], pos[N];
int J[N]; 

int tr[N<<2], tag[N<<2];
inline void build(int p, int pl, int pr){
	tr[p] = tag[p] = 0;
	if(pl==pr) return ;
	int mid = pl+pr>>1;
	build(ls(p), pl, mid);
	build(rs(p), mid+1, pr);
}

inline void push_down(int p, int pl, int pr){
	tag[ls(p)] = tag[rs(p)] = 1;
	int mid = pl + pr >> 1;
	tr[ls(p)] = mid - pl + 1;
	tr[rs(p)] = pr - mid;
	tag[p] = 0;
}

inline void update(int p, int pl, int pr, int l, int r){
	if(l <= pl && pr <= r) {
		tr[p] = pr - pl + 1;
		tag[p] = 1;
		return ;
	}
	if(tag[p]) push_down(p, pl, pr);
	int mid = pl + pr >> 1;
	if(l <= mid) update(ls(p), pl, mid, l, r);
	if(r > mid) update(rs(p), mid+1, pr, l, r);
	tr[p] = tr[ls(p)] + tr[rs(p)];
}

inline int query(int p, int pl, int pr, int l, int r){
	if(pl>=l && pr<=r) return tr[p];
	if(tag[p]) push_down(p, pl, pr);
	int mid = pl+pr>>1, res = 0;
	if(r<=mid) res += query(ls(p), pl, mid, l, r);
	if(l>mid) res += query(rs(p), mid+1, pr, l, r);
	return res;
}

set<int> st;
bool vis[N];
struct node{
	int l, r;
}block[N];

int f[N];
inline int find(int x){
	return x==f[x] ? x : f[x] = find(f[x]);
}
inline void merge(int x, int y){//把y合并到x里 
	x = find(x), y = find(y);
	f[y] = x;
	chkmin(block[x].l, block[y].l);
	chkmax(block[x].r, block[y].r);
}

inline void sol(){
	cin >> n >> c;
	st.clear();
	
	for(int i=1;i<=n;i++){
		cin >> a[i];
		pos[a[i]] = i;
		f[i] = i;
		block[i] = {i, i};
		vis[i] = 0;
	}
//	build(1,1,n);//线段树只是用来统计 【段】并上【点】 的覆盖总和 
	
	st.insert(0);
	st.insert(n+1);
	
	int ans = 1;
	for(int i=1;i<=n;i++){
		int x = pos[i];
		vis[x] = 1;
		auto p = st.upper_bound(x);
		int L = *prev(p), R = *p; 
		//先判断在不在【段】里
		
		int anc = find(x);
		if(block[anc].l ^ block[anc].r){
			//在段里 下一步要扩展merge 
			int nowl = block[anc].l, nowr = block[anc].r;
			if(L >= nowl){
				//左边不可能是可扩展的
			}else{
				int LL = *prev(st.upper_bound(nowl));
				if(nowl - c > LL){
					for(int j=nowl-c;j<nowl;j++){
						merge(anc, j);
					}
				}else{
					for(int j=LL+1;j<nowl;j++){
						merge(anc, j);
					}
				}
			} 
			
			if(R <= nowr){
				//右边不可能是可扩展的
			}else{
				int RR = *(st.upper_bound(nowr));
				if(nowr + c < RR){
					for(int j=nowr+1;j<=nowr+c;j++){
						merge(anc, j);
					}
				}else{
					for(int j=nowr+1;j<RR;j++){
						merge(anc, j);
					}
				}
			}
			
			int ret = 0;
			if(x > pos[1]){
				for(int j=max(block[anc].l, pos[1]+1);j<=block[anc].r;j++){
					if(!vis[j]) ++ret;
				}
				if(ret) ans = ans * ret % mod;
			}else if(x < pos[1]){
				for(int j=block[anc].l;j<=min(pos[1]-1, block[anc].r);j++){
					if(!vis[j]) ++ret;
				}
				if(ret) ans = ans * ret % mod;
			}
			
//			update(1,1,n,block[anc].l, block[anc].r);
		}else{
			//不在段里 下一步要扩展merge 
			if(x - c > L){
				for(int j=x-c;j<x;j++){
					merge(x, j);
				}
			}
			if(x + c < R){
				for(int j=x+1;j<=x+c;j++){
					merge(x, j);
				}
			}
			
			int ret = 0;
			if(x > pos[1]){
				for(int j=max(block[x].l, pos[1]+1);j<=block[x].r;j++){
					if(!vis[j]) ++ret;
				}
				if(ret) ans = ans * ret % mod;
			}else if(x < pos[1]){
				for(int j=block[x].l;j<=min(pos[1]-1, block[x].r);j++){
					if(!vis[j]) ++ret;
				}
				if(ret) ans = ans * ret % mod;
			}else{
				for(int j=block[x].l;j<=block[x].r;j++){
					if(!vis[j]) ++ret;
				}
				if(ret) ans = ans * ret % mod;
			}
//			update(1,1,n,block[x].l,block[x].r);
		}
		
		st.insert(x);
//		cout << " " << ans << endl;
//		int sum = query(1,1,n,1,n);
	}
	cout << ans << endl;
}

signed main(){
#ifdef LOCAL
	clock_t CLOCK_S = clock();
	freopen("1.in", "r", stdin);
#endif
	
	IOS;
	J[0] = 1;
	for(int i=1;i<N;i++){
		J[i] = J[i-1] * i % mod;
	}
	
	int tc = 1;
	cout << fixed << setprecision(2);
	cin >> tc;
	while(tc--){
		sol();
	}
	
#ifdef LOCAL
	clock_t CLOCK_E = clock();
	cerr << "Judging Time: " << 1.00 * (CLOCK_E - CLOCK_S) / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}
/*
5 4
1 3 2 5 4
*/

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 17920kb

input:

5
5 3
3 4 2 1 5
5 4
4 2 1 3 5
5 2
4 5 3 1 2
5 3
4 3 2 1 5
5 2
2 3 1 5 4

output:

6
1
4
6
4

result:

ok 5 number(s): "6 1 4 6 4"

Test #2:

score: -100
Wrong Answer
time: 53ms
memory: 15892kb

input:

100000
5 4
1 3 2 5 4
5 3
5 1 4 2 3
5 2
1 4 5 3 2
5 4
5 2 4 3 1
5 4
2 5 4 1 3
5 4
1 2 3 5 4
5 4
4 3 2 5 1
5 3
1 5 4 3 2
5 3
3 2 5 4 1
5 4
4 3 1 5 2
5 4
4 3 5 2 1
5 2
3 2 1 4 5
5 3
2 4 5 1 3
5 3
2 1 4 3 5
5 3
2 1 5 4 3
5 2
2 1 3 4 5
5 4
2 3 1 4 5
5 2
1 2 4 5 3
5 3
2 4 1 5 3
5 3
2 4 3 5 1
5 3
4 1 3 5 2...

output:

24
6
12
24
1
24
24
18
18
1
24
4
6
6
6
4
1
12
1
18
6
24
18
4
18
4
6
18
18
6
4
1
18
18
1
18
24
18
6
1
12
18
6
4
4
24
12
4
24
4
4
24
18
1
1
1
1
6
1
4
1
18
1
18
4
4
6
24
18
4
6
1
12
1
4
4
6
24
18
6
4
18
1
12
6
24
1
4
12
1
1
6
1
1
24
12
18
1
4
18
1
4
24
6
4
24
6
24
1
1
6
1
18
24
1
4
1
1
4
6
1
6
4
18
1
24...

result:

wrong answer 3rd numbers differ - expected: '6', found: '12'