QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#222808#5047. PermutationabsintheWA 42ms3836kbC++234.1kb2023-10-21 18:52:472023-10-21 18:52:48

Judging History

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

  • [2023-10-21 18:52:48]
  • 评测
  • 测评结果:WA
  • 用时:42ms
  • 内存:3836kb
  • [2023-10-21 18:52:47]
  • 提交

answer

// problem-url: https://qoj.ac/contest/1039/problem/5047

#if not LOCAL
#define NDEBUG 1
#endif
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(auto i = a; i < (b); ++i)
#define down(x, a) for (auto x = a; x--;)
#define all(x) begin(x), end(x)
#define sz(x) int(size(x))
#define let auto const

using ll = long long;
using lint = ll;
using pii = pair<int, int>;
using vi = vector<int>;

let mod=998244353;

// { ==== Begin library /home/user202729/icpc-trd/content/number-theory/ModularArithmetic.h ====
/**
 * Author: user202729
 * Date: 2023-10-09
 * License: CC0
 * Source: folklore
 * Status: not tested very well
 * Description: Operators for modular arithmetic. You need to set {\tt mod} to
 * some number first and then you can use the structure.
 */



// { ==== Begin library euclid.h ====
/**
 * Author: Unknown
 * Date: 2002-09-15
 * Source: predates tinyKACTL
 * Description: Finds two integers $x$ and $y$, such that $ax+by=\gcd(a,b)$. If
 * you just need gcd, use the built in \texttt{\_\_gcd} instead.
 * If $a$ and $b$ are coprime, then $x$ is the inverse of $a \pmod{b}$.
 */



ll euclid(ll a, ll b, ll &x, ll &y) {
	if (!b) return x = 1, y = 0, a;
	ll d = euclid(b, a % b, y, x);
	return y -= a/b * x, d;
}

// } ==== End library euclid.h ====


struct Mod {
	int x;
	Mod(int y=0) : x(y%mod) { if(x<0) x+=mod; }
	static Mod raw(int y){ Mod r; r.x=y; return r; }
	void operator+=(Mod b) { if((x+=b.x)>=mod) x-=mod; }
	void operator-=(Mod b) { if((x-=b.x)<0) x+=mod; }
	Mod operator-() const { return 0-*this; }
	void operator*=(Mod b) { x=int(ll(x) * b.x % mod); }
	explicit operator int() const{return x;}
		
	[[nodiscard]] Mod pow(auto p) const {
		assert(p>=0);
		Mod a=*this;
		Mod ans = 1; for (; p; p >>= 1, a *= a) if (p&1) ans *= a;
		return ans;
	}

	[[nodiscard]] Mod inv() const {
		assert(x!=0);
		return pow(mod-2);
		//ll z, y, g = euclid(mod, x, z, y); assert(g == 1); return int(y);
	}
	void operator/=(Mod b) { *this *= b.inv(); }

#define A(O) [[nodiscard]] friend Mod operator O(Mod a, Mod b) { a O##= b; return a; }
	A(+) A(-) A(*) A(/)
#undef A

#define C(O) [[nodiscard]] bool operator O(Mod b) const { return x O b.x; }
	C(==) C(!=) C(<) C(>) C(<=) C(>=)
#undef C
};

// } ==== End library /home/user202729/icpc-trd/content/number-theory/ModularArithmetic.h ====


int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin.exceptions(cin.failbit);
	int t; cin>>t;
	down(_, t){
		int n; cin>>n;
		int c; cin>>c;
		vector<int> pos(n);
		rep(i, 0, n){
			int val; cin>>val; --val;
			pos[val]=i;
		}

		struct Block{
			int rightEnd, leftExtent, leftVal, rightExtent, rightVal;
		};
		map<int, Block> ranges;
		ranges.insert({0, {n, 0, -1, n, -1}});
		vector<int> par(n, -1);
		vector<int> len(n);
		rep(val, 0, n){
			let p=pos[val];
			let iter=--ranges.upper_bound(p);
			auto& [leftEnd, block]=*iter;
			auto& [rightEnd, leftExtent, leftVal, rightExtent, rightVal]=block;
			assert(p<rightEnd);
			assert(leftEnd<=leftExtent);
			assert(leftExtent<=rightExtent);
			assert(rightExtent<=rightEnd);

			int left=p, right=p+1;
			down(_, 2){
				if(leftExtent!=0 and left-leftExtent<c and leftEnd+(leftEnd==0)+c<=n) left=leftEnd, right=max(right, min(rightEnd, leftExtent+c));
				if(rightExtent!=n and rightExtent-right<c and rightEnd-(rightEnd==n)-c>=0) right=rightEnd, left=min(left, max(leftEnd, rightExtent-c));
			}
			if(left==leftEnd){
				assert(right>=leftExtent);
				if(leftVal>=0) par[leftVal]=val;
				leftVal=val, leftExtent=right;
				if(right==rightEnd){
					if(rightVal>=0) par[rightVal]=val;
					rightVal=-1, rightExtent=rightEnd;
				}
			}else if(right==rightEnd){
				assert(left<=rightExtent);
				if(rightVal>=0) par[rightVal]=val;
				rightVal=val, rightExtent=left;
				assert(left!=leftEnd);
			}else{
				let oldRightEnd=rightEnd;
				rightExtent=rightEnd=p;
				ranges.insert(iter, {p+1, {oldRightEnd, p+1, -1, oldRightEnd, -1}});
			}
			len[val]=right-left;
			//assert(cerr<<val<<":"<<left<<' '<<right<<'\n');
		}
		vector<int> used(n);
		Mod answer=1;
		rep(val, 0, n){
			answer*=len[val]-used[val];
			if(par[val]>=0) used[par[val]]+=used[val]+1;
		}
		cout<<int(answer)<<'\n';
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3836kb

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: 42ms
memory: 3640kb

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
6
24
2
24
24
6
18
1
24
4
6
6
6
4
1
12
1
6
6
24
18
2
18
4
6
6
18
6
4
1
6
18
1
6
24
18
6
1
12
18
6
4
2
24
12
4
24
4
4
24
6
1
0
0
1
6
1
4
1
18
1
18
4
4
6
24
6
4
6
1
12
2
4
4
6
24
18
6
2
6
1
12
6
24
2
4
6
1
1
6
0
1
24
12
18
1
4
18
1
4
24
6
4
24
6
24
0
2
6
1
18
24
1
4
1
1
2
6
1
6
4
18
1
24
6
6
4
24
...

result:

wrong answer 5th numbers differ - expected: '1', found: '2'