Submission #347243

#TimeUsernameProblemLanguageResultExecution timeMemory
347243kingfran1907Matching (CEOI11_mat)C++14
36 / 100
604 ms65540 KiB
#include <bits/stdc++.h>
#define X first
#define Y second

using namespace std;
typedef long long llint;

const int maxn = 1e6+10;
const int base = 1000133;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int logo = 20;
const int off = 1 << logo;
const int treesiz = off << 1;

int n, m;
int a[maxn], b[maxn];
vector< int > v;
int pot[maxn];
set< int > ms;
int tour[treesiz], prop[treesiz];
int loga[maxn];

void updcnt(int x, int val) {
	for (x++; x < maxn; x += x & -x)
		loga[x] += val;
}

int ccnt(int x) {
	int out = 0;
	for (x++; x > 0; x -= x & -x)
		out += loga[x];
	return out;
}

int mul(int x, int y) {
	llint out = (llint)x * y;
	return out % mod;
}

int pote(int a, int b) {
	if (b == 0) return 1;
	else if (b % 2 == 1) return mul(a, pote(a, b - 1));
	else {
		int out = pote(a, b / 2);
		return mul(out, out);
	}
}

int inv(int x) {
	return pote(base, mod - 2);
}

void send(int node) {
	tour[node * 2] = mul(tour[node * 2], prop[node]);
	tour[node * 2 + 1] = mul(tour[node * 2 + 1], prop[node]);
	
	prop[node * 2] = mul(prop[node * 2], prop[node]);
	prop[node * 2 + 1] = mul(prop[node * 2 + 1], prop[node]);
	prop[node] = 1;
}

void update(int a, int b, int l, int r, int node, int val) {
	if (l > b || r < a) return;
	if (l >= a && r <= b) {
		tour[node] = val;
		prop[node] = 1;
		return;
	}
	
	int mid = (l + r) / 2;
	send(node);
	update(a, b, l, mid, node * 2, val);
	update(a, b, mid + 1, r, node * 2 + 1, val);
	tour[node] = (tour[node * 2] + tour[node * 2 + 1]) % mod;
}

int query(int a, int b, int l, int r, int node) {
	if (l > b || r < a) return 0;
	if (l >= a && r <= b) return tour[node];
	
	int mid = (l + r) / 2;
	send(node);
	return (query(a, b, l, mid, node * 2) + query(a, b, mid + 1, r, node * 2 + 1));
}

void updat(int a, int b, int l, int r, int node, int val) {
	if (l > b || r < a) return;
	if (l >= a && r <= b) {
		tour[node] = mul(tour[node], val);
		prop[node] = mul(prop[node], val);
		return;
	}
	
	int mid = (l + r) / 2;
	send(node);
	updat(a, b, l, mid, node * 2, val);
	updat(a, b, mid + 1, r, node * 2 + 1, val);
	tour[node] = (tour[node * 2] + tour[node * 2 + 1]) % mod;
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++)
		scanf("%d", a+i);
	for (int i = 0; i < m; i++) 
		scanf("%d", b+i);
	
	for (int i = 0; i < m; i++)
		v.push_back(b[i]);
	sort(v.begin(), v.end());
	for (int i = 0; i < m; i++) {
		b[i] = lower_bound(v.begin(), v.end(), b[i]) - v.begin();
	}
	
	pot[0] = 1;
	for (int i = 1; i <= m; i++) pot[i] = mul(pot[i - 1], base);
	for (int i = 1; i < treesiz; i++) prop[i] = 1;
	
	int has = 0;
	int divs = inv(base);
	assert(mul(base, divs) == 1);
	vector< int > sol;
	
	has = 0;
	reverse(a, a + n);
	for (int i = 0; i < n; i++) {
		a[i]--;
		has = mul(has, base), has += a[i];
		has %= mod;
	}
	//printf("has == %d\n", has);
	
	int sum = 0;
	for (int i = 0; i < n; i++) sum += pot[i], sum %= mod;
	
	ms.insert(has);
	for (int i = 0; i <= m; i++) {
		has += sum;
		has %= mod;
		ms.insert(has);
	}
	
	for (int i = 0; i <= m - n; i++) {
		if (i == 0) {
			for (int j = 0; j < n; j++) {
				updcnt(b[j], 1);
			}
			
			for (int j = 0; j < n; j++) {
				int tren = ccnt(b[j]) - 1;
				
				int ac = mul(j, pot[tren]);
				//printf("first %d(%d) %d -- %d (%d)\n", j, b[j], tren, pot[tren], ac);
				update(b[j], b[j], 0, off - 1, 1, ac);
			}
			if (ms.count(tour[1])) sol.push_back(i);
		} else {
			int ac = b[i + n - 1];
			int cnt = ccnt(ac);
			//printf("i > 0: (%d) -> %d\n", ac, cnt);
			
			updcnt(ac, 1);
			update(ac, ac, 0, off - 1, 1, mul(i + n - 1, pot[cnt]));
			updat(ac + 1, off - 1, 0, off - 1, 1, base);
			
			int ths = tour[1];
			if (ms.count(ths)) sol.push_back(i);
		}
		//printf("debug: %d --> %d\n", i, tour[1]);
		
		update(b[i], b[i], 0, off - 1, 1, 0);
		//printf("fr: %d\n", tour[1]);
		updat(b[i] + 1, off - 1, 0, off - 1, 1, divs);
		updcnt(b[i], -1);
		//printf("after: %d --> %d\n", i, tour[1]);
	}
	
	printf("%d\n", sol.size());
	for (int i = 0; i < sol.size(); i++) {
		printf("%d ", sol[i] + 1);
	}
	return 0;
}

Compilation message (stderr)

mat.cpp: In function 'int main()':
mat.cpp:179:11: warning: format '%d' expects argument of type 'int', but argument 2 has type 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wformat=]
  179 |  printf("%d\n", sol.size());
      |          ~^     ~~~~~~~~~~
      |           |             |
      |           int           std::vector<int>::size_type {aka long unsigned int}
      |          %ld
mat.cpp:180:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  180 |  for (int i = 0; i < sol.size(); i++) {
      |                  ~~^~~~~~~~~~~~
mat.cpp:103:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  103 |  scanf("%d%d", &n, &m);
      |  ~~~~~^~~~~~~~~~~~~~~~
mat.cpp:105:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  105 |   scanf("%d", a+i);
      |   ~~~~~^~~~~~~~~~~
mat.cpp:107:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  107 |   scanf("%d", b+i);
      |   ~~~~~^~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...