BZOJ4006【分块】

来源:互联网 发布:研究生程序员 编辑:程序博客网 时间:2024/05/19 07:42

不会写hash表.于是就用hash_map卡过去了.

/* I will wait for you*/#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <algorithm>#include <iostream>#include <fstream>#include <vector>#include <queue>#include <deque>#include <map>#include <set>#include <string>#include <ext/hash_map>#define make make_pair#define fi first#define se secondusing namespace std;using namespace __gnu_cxx;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;const int maxn = 100010;const int maxm = 1010;const int maxs = 26;const int inf = 0x3f3f3f3f;const int P = 1000000007;const double error = 1e-9;inline ll read(){ll x = 0, f = 1;char ch = getchar();while (ch <= 47 || ch >= 58)f = (ch == 45 ? -1 : 1), ch = getchar();while (ch >= 48 && ch <= 57)x = x * 10 + ch - 48, ch = getchar();return x * f;}int n, q, blo, cnt, bel[maxn], num[maxn], Gcd[maxm], Xor[maxm];hash_map<int, int> m[maxm];int gcd(int a, int b){return b ? gcd(b, a % b) : a;}void solve(int i){int l = (i - 1) * blo + 1;    int r = min(n, i * blo);    Gcd[i] = num[l], Xor[i] = 0;m[i].clear();for (int j = l; j <= r; j++) {Gcd[i] = gcd(Gcd[i], num[j]);Xor[i] ^= num[j];if (m[i][Xor[i]] == 0)m[i][Xor[i]] = j; }}void init(){for (int i = 1; i <= cnt; i++)solve(i);}void change(int u, int c){int i = (u - 1) / blo + 1;num[u] = c, solve(i);}int tmp1, tmp2;int query(ll c){int tmpgcd = num[1], tmpxor = 0;for (int i = 1; i <= cnt; i++) {if (i == 1 || Gcd[i] % tmpgcd != 0) {int l = (i - 1) * blo + 1;int r = min(n, i * blo);tmp1++;for (int j = l; j <= r; j++) {tmpgcd = gcd(tmpgcd, num[j]);tmpxor ^= num[j];if ((ll) tmpxor * tmpgcd == c)return j;}}else {tmp2++;int t = (ll) (c / tmpgcd) ^ tmpxor;if (m[i][t])return m[i][t];tmpgcd = gcd(tmpgcd, Gcd[i]);tmpxor ^= Xor[i];}}return 0;}int main(){n = read(), blo = (int) sqrt(n);for (int i = 1; i <= n; i++) {num[i] = read(), bel[i] = i / blo + 1;cnt = max(cnt, bel[i]);}q = read(), init();for (int i = 1; i <= q; i++) {char s[10]; scanf("%s", s);if (s[0] == 'M') {int u = read(), c = read();change(u + 1, c);}if (s[0] == 'Q') {ll c = read(), t = query(c);if (t)printf("%d\n", t - 1);elseprintf("no\n");}}return 0;}

0 0
原创粉丝点击