QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#870126#8618. Have You Seen This Subarray?ucup-team5008#ML 0ms0kbC++203.8kb2025-01-25 14:56:232025-01-25 14:56:25

Judging History

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

  • [2025-01-25 14:56:25]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2025-01-25 14:56:23]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define rep2(i,j,k) for(ll i=ll(j); i<ll(k); i++)
#define rep(i,j) rep2(i,0,j)
#define rrep2(i,j,k) for(ll i=ll(j)-1;i>=ll(k);i--)
#define rrep(i,j) rrep2(i,j,0)
#define SZ(a) ll(a.size())
#define all(a) a.begin(),a.end()
#define eb emplace_back
using ll=long long;
using vl=vector<ll>;
using vvl=vector<vl>;
using P=pair<ll,ll>;
using vp=vector<P>;
using vvp=vector<vp>;
const ll inf=LLONG_MAX/4;
template<typename T>
bool chmin(T& a,T b){return a>b?a=b,1:0;}
template<typename T>
bool chmax(T& a,T b){return a<b?a=b,1:0;}
void n_large(ll n,ll m,ll q){
	vvp query(n);
	vl a(n);
	rep(i,n) a[i]=i;
	rep(i,m){
		ll x,y;cin>>x>>y;
		--x,--y;
		query[a[x]].eb(i,y);
		query[a[y]].eb(i,x);
		swap(a[x],a[y]);
	}
	vector<int> used(n, -1);
	int iter = 0;
	while(q--){
		ll k;cin>>k;
		vl b(k);
		vl curr(k);
		++iter;
		bool ok = true;
		rep(i,k) {
			cin>>b[i], --b[i], curr[i]=b[i];
			if(used[b[i]] == iter) ok = false;
			used[b[i]] = iter;
		}
		if(!ok) continue;
		vector<tuple<ll,ll,ll>> c;
		rep(i,k){
			for(auto el2:query[b[i]]) c.eb(el2.first,i,el2.second);
		}
		sort(all(c));
		ll ans=-1;
		ll last=-1;
		ll cnt=0;
		rep(i,k){
			if(curr[i]==curr[0]+i) cnt++;
		}
		for(auto [idx,i,j]: c){
			if(last != idx){
				if(cnt==k){
					ans=last;
					break;
				}
			}
			if(curr[i]==curr[0]+i) cnt--;
			curr[i]=j;
			if(curr[i]==curr[0]+i) cnt++;
			if(i==0){
				cnt=0;
				rep(f,k){
					if(curr[f]==curr[0]+f) cnt++;
				}
			}
			last=idx;
		}
		if(ans==-1) ans=last;
		ans++;
		cout<<ans<<"\n";
	}

}
struct state {
	std::map<int, int> to;
	int len, link, ind;
};
const int THR = 50;
const int N = 100000 * THR * 2 + 3;
state gl_sa[N];
struct suffix_automaton {
	state *sa;
	int last, size;
	void init(int mxsize) {
		sa = gl_sa;
		sa[0].len = 0;
		sa[0].link = -1;
		last = 0;
		size = 1;
	}
	suffix_automaton(int mxsize) {
		init(mxsize);
	}
	int add_c(int c, int ind) {
		int cur = last;
		int added_id = size++;
		last = added_id;
		sa[last].len = sa[cur].len + 1;
		sa[last].ind = ind;
		do {
			sa[cur].to[c] = last;
			cur = sa[cur].link;
		} while (cur != -1 && !sa[cur].to.count(c));
		if (cur == -1) sa[last].link = 0;
		else if (sa[sa[cur].to[c]].len == sa[cur].len + 1) sa[last].link = sa[cur].to[c];
		else {
			int k = sa[cur].to[c];
			sa[size] = state(sa[k]);
			//sa[size].to = std::map<int, int>(sa[k].to);
			sa[size].len = sa[cur].len + 1;
			sa[size].ind = ~(1 << 31);
			sa[last].link = sa[k].link = size;
			do {
				sa[cur].to[c] = size;
				cur = sa[cur].link;
			} while (cur != -1 && sa[cur].to[c] == k);
			++size;
		}
		return added_id;
	}
};

void n_small(int n, int m, int q) {
	vector<int> now(n);
	iota(all(now), 0);
	vector<int> v = now;
	rep(i,m){
		ll x,y;cin>>x>>y;
		--x,--y;
		swap(now[x], now[y]);
		v.eb(n + 1);
		v.insert(v.end(), all(now));
	}
	suffix_automaton au(v.size());
	int ind = 0;
	for (int i = 0; i < (int)v.size(); ++i) {
		au.add_c(v[i], ind);
		if (v[i] == n + 1) ++ind;
	}
	printf("\n");
	std::vector<std::pair<int, int> > ord(au.size);
	for (int i = 0; i < au.size; ++i) ord[i] = std::make_pair(au.sa[i].len, i);
	std::sort(ord.begin(), ord.end());
	for (int i = ord.size() - 1; i > 0; --i) {
		int id = ord[i].second;
		au.sa[au.sa[id].link].ind = std::min(au.sa[au.sa[id].link].ind, au.sa[id].ind);
	}
	while(q--) {
		int k;
		cin >> k;
		vector<int> b(k);
		rep(i, k) cin >> b[i], --b[i];
		int cur = 0;
		bool ok = 1;
		for (int i = 0; i < (int)b.size() && ok; ++i) cur = au.sa[cur].to[b[i]];
		printf("%d\n", au.sa[cur].ind);
	}
}
int main(){
	/*
	suffix_automaton au;
	char s[10];
	scanf("%s", s);
	for (int i = 0; s[i]; ++i) au.add_c(s[i] - 'a');
	int diff = 0;
	for (int i = 1; i < au.size; ++i) diff += au.sa[i].len - au.sa[au.sa[i].link].len;
	printf("%d\n", diff);
	return 0;
	*/
	cin.tie(0)->sync_with_stdio(0);
	int n,m,q;
	cin >> n >> m >> q;
	if(n <= 50) n_small(n,m,q);
	else n_large(n,m,q);
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Memory Limit Exceeded

input:

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

output:


1
3
0
2
3

result: