w33z8kqrqk8zzzx33
2020-12-26 22:38:57
众所周知
以下默认
定理:块状链表总共
引理:找第
引理:插入的时间复杂度是
引理:删除的时间复杂度是
于是整体任何操作的时间复杂度保证为
题意:在第
模板题。操作和以上描述的一样,还少了一个删除?话说为什么数据随机 关于实现细节,可以外层叫“链表”的东西仍然用
题意:维护一个字符串,支持插入一串,删除一串,询问一串。
首先,move prev next 都是同一个操作穿不同的外装,维护一个正整数代表当前指针。
这里,如果按照以上方法暴力一个一个加入一个一个删除,操作复杂度
接下来证明时间复杂度。
定理:对第一情况,“维护”和初始化一个关于维护的
引理:插入时间复杂度是
引理:删除时间复杂度是
引理:输出时间复杂度为
虽然长度能到 2e6,虽然卡满可以调用 3e6 次输出,STL 的常数是超级小。注意这里可以用
题意:维护一个 order statistic 集合。
首先,我们可以把“无序”变成“有序”:选择维护当前集合的排序顺序。
我们第一需要实现是找到一个元素会在哪里插入来保证有序性。如果一整个块状链表是有序,那么所有内层
插入就直接这样(套普通块状链表插入方法)实现了,删除同理。第
接下来就是
块状链表可以称作“五分钟写完的平衡树”。
众所周知莫队是分块,但是莫队不是数据结构
你真觉得我会讲暴力莫队吗
注意直接 naive 莫队是过不了的。
考虑用
炸 出 翔
我们可以离线,然后已经在逐块处理,可以在一个块内两个修改之间的整块询问对
发现单点修改仅仅会影响
于是做到了一个
考虑我们把询问矩形分开来成若干行区间和列区间,怎么计算答案?
(R1C1) | (R1C2) | (R1C3) |
---|---|---|
(R2C1) | (R2C2) | (R2C3) |
(R3C1) | (R3C2) | (R3C3) |
贡献的对可以分为几类。
注意第一类会在第二类包含,并且第二类会统计第一类两次,所以需要容斥出来。形式化:
如果我们按照树套树的子矩形来维护答案的话,可以做到
接下来讲实现细节:
接下来讲卡常方法:
接下来讲卡内存方法:
发现我们现在内存复杂度是
dfs 到一个外层线段树节点上,建立内层线段树,用完然后把内层线段树的所有关键节点都清零。最重要是现在都不需要动态开点了,大大减少时空常数。最后需要注意我们离线的方法。不应该在每一个线段树节点上方
仍然有继续卡常的余地:
首先,区间满足某条件(
我们需要
这个可以拆成两个部分:
所以其实
定义:
贡献就等于了:
由于
但是实际上开一个
最终时间复杂度
没封装
#include <bits/stdc++.h>
using namespace std;
#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, (a))
#define rep1(i, a) iter(i, 1, (a)+1)
using vi=vector<int>;
vector<vi> kzlb;
const int th=300;
pair<int, vi::iterator> fin(int kth) {
rep(i, kzlb.size()) {
if(kth < kzlb[i].size()) return {i, kzlb[i].begin()+kth};
kth -= kzlb[i].size();
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int n; cin >> n;
vi ar(n+1);
rep(i, n) cin >> ar[i];
int l=0;
while(l != n+1) {
int r = min(n+1,l+th);
kzlb.emplace_back(ar.begin()+l, ar.begin()+r);
l=r;
}
rep(i, n) {
int o, l, r, c; cin >> o >> l >> r >> c;
if(o == 0) {
l--;
auto v = fin(l);
int i = v.first;
kzlb[i].insert(v.second, r);
if(kzlb[i].size() == 2*th) {
kzlb.emplace(kzlb.begin()+i+1, kzlb[i].begin()+th, kzlb[i].end());
kzlb[i].erase(kzlb[i].begin()+th, kzlb[i].end());
}
} else cout << *fin(r-1).second << endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, (a))
#define rep1(i, a) iter(i, 1, (a)+1)
#define fi first
#define se second
char inpf[1<<23],oupf[1<<23];
char *inp=inpf,*oup=oupf;
string gl() {
string v;
char tmp=*(inp++);
while(tmp == '\n' || tmp == '\r') tmp = *(inp++);
while(tmp != '\n' && tmp != '\r') { v += tmp; tmp = *(inp++); }
return v;
}
vector<string> kzlb;
const int th=3000;
pair<int,int> gt(int idx) {
rep(i, kzlb.size()) {
if(idx < kzlb[i].size()) return {i, idx};
idx -= kzlb[i].size();
}
return {0, 0};
}
void maintain(int idx) {
if(idx == kzlb.size()) return;
if(kzlb[idx].size() == 0) {
kzlb.erase(kzlb.begin()+idx);
maintain(idx);
} else if(kzlb[idx].size() > 2*th) {
kzlb.emplace(kzlb.begin()+idx+1, kzlb[idx].substr(kzlb[idx].size()-th));
kzlb[idx].erase(kzlb[idx].size()-th);
maintain(idx);
}
}
int main() {
fread(inpf, 1, 1<<23, stdin);
int n = stol(gl()), k = 0;
kzlb.push_back("!");
string d, st;
while(n--) {
istringstream com(gl()); com >> d;
if(d == "Insert") {
int n; com >> n;
st = gl();
while(st.size() != n) st += gl();
auto v = gt(k);
kzlb[v.fi].insert(v.se, st);
maintain(v.fi);
}
if(d == "Move") com >> k;
if(d == "Delete") {
int n; com >> n;
auto v = gt(k); int i=v.fi;
while(n) {
int st=v.se, en=min(st+n,(int)kzlb[i].size());
kzlb[i].erase(st, en-st);
n -= en-st;
i++;v.se=0;
}
maintain(v.fi);
}
if(d == "Get") {
int n; com >> n;
auto v = gt(k); int i=v.fi;
while(n) {
int st=v.se, en=min(st+n,(int)kzlb[i].size());
iter(j, st, en) *(oup++) = (kzlb[i][j]);
n -= en-st;
i++;v.se=0;
}
*(oup++) = ('\n');
}
if(d == "Prev") k--;
if(d == "Next") k++;
// for(string i:kzlb) cout << i;
// cout << endl;
}
fwrite(oupf, 1, oup-oupf, stdout);
return 0;
}
// writer: w33z8kqrqk8zzzx33
#include <bits/stdc++.h>
using namespace std;
// begin fast read template by CYJian (source: https://www.luogu.com.cn/paste/i11c3ppx)
namespace io {
const int __SIZE = (1 << 21) + 1;
char ibuf[__SIZE], *iS, *iT, obuf[__SIZE], *oS = obuf, *oT = oS + __SIZE - 1, __c, qu[55]; int __f, qr, _eof;
#define Gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
inline void flush () { fwrite (obuf, 1, oS - obuf, stdout), oS = obuf; }
inline void gc (char &x) { x = Gc(); }
inline void pc (char x) { *oS ++ = x; if (oS == oT) flush (); }
inline void pstr (const char *s) { int __len = strlen(s); for (__f = 0; __f < __len; ++__f) pc (s[__f]); }
inline void gstr (char *s) { for(__c = Gc(); __c < 32 || __c > 126 || __c == ' ';) __c = Gc();
for(; __c > 31 && __c < 127 && __c != ' '; ++s, __c = Gc()) *s = __c; *s = 0; }
template <class I> inline bool gi (I &x) { _eof = 0;
for (__f = 1, __c = Gc(); (__c < '0' || __c > '9') && !_eof; __c = Gc()) { if (__c == '-') __f = -1; _eof |= __c == EOF; }
for (x = 0; __c <= '9' && __c >= '0' && !_eof; __c = Gc()) x = x * 10 + (__c & 15), _eof |= __c == EOF; x *= __f; return !_eof; }
template <class I> inline void print (I x) { if (!x) pc ('0'); if (x < 0) pc ('-'), x = -x;
while (x) qu[++ qr] = x % 10 + '0', x /= 10; while (qr) pc (qu[qr --]); }
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
} using io::pc; using io::gc; using io::pstr; using io::gstr; using io::gi; using io::print;
// end fast read template by CYJian
#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, a)
#define rep1(i, a) iter(i, 1, (a)+1)
#define log(a) cerr<<"\033[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"\033[0m"<<endl
#define all(a) a.begin(), a.end()
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using ll=long long;
using pii=pair<int, int>;
//#define int ll
const int MOD = 1000000007;
const int sz=1000,th=2*sz;
using vi=vector<int>;
struct Splay {
vector<vi> dt;
Splay(vi q){
sort(all(q));
dt.emplace_back();
rep(i,q.size()){
dt.back().push_back(q[i]);
if(dt.back().size() == sz) dt.emplace_back();
}
if(!dt.back().size())dt.pop_back();
}
int get(int p){
int las=-2e9;
rep(i,dt.size()){
if(las<p&&p<=dt[i].back())return i;
las=dt[i].back();
}
return -1;
}
void ins(int p){
int it=get(p);
dt[it].emplace(lower_bound(all(dt[it]),p),p);
if(dt[it].size()>th){
dt.emplace(dt.begin()+it+1,dt[it].end()-sz,dt[it].end());
dt[it].erase(dt[it].end()-sz,dt[it].end());
}
}
void ers(int p) {
int it=get(p);
dt[it].erase(lower_bound(all(dt[it]),p));
if(!dt[it].size())dt.erase(dt.begin()+it);
}
int kth(int p){
for(vi&v:dt){if(v.size()<=p)p-=v.size();else return v[p];}
}
int clt(int p){
int ans=0;for(vi&v:dt){
if(v.back()<p)ans+=v.size();
else{for(int&i:v)ans+=(i<p);break;}
}
return ans;
}
int pre(int p){
int it=get(p);
auto ps=lower_bound(all(dt[it]),p);
if(ps==dt[it].begin())return dt[it-1].back();
return *prev(ps);
}
int nex(int p){
int it=get(p);
auto ps=upper_bound(all(dt[it]),p);
if(ps==dt[it].end())return dt[it+1].front();
return *ps;
}
};
signed main() {
// ios_base::sync_with_stdio(false); cin.tie(0);
int n=0,m;
gi(n);
gi(m);
vector<int> ar(n);
rep(i, n) gi(ar[i]);
ar.pb(2e9);
Splay sp(ar);
int la = 0; ll sm = 0;
rep1(i, m) {
// cerr << i << ' ';
int op,x;
gi(op), gi(x);
// cin >> op >> x;
x ^= la;
if(op == 1) sp.ins(x);
if(op == 2) sp.ers(x);
if(op == 3) sm ^= (la = (sp.clt(x)+1));
if(op == 4) sm ^= (la = sp.kth(x-1));
if(op == 5) sm ^= (la = sp.pre(x));
if(op == 6) sm ^= (la = sp.nex(x));
// cerr << la << endl;
// sp.dfs(sp.rt); cerr << endl;
// return 0;
}
print(sm);
}
// writer: w33z8kqrqk8zzzx33
#include <bits/stdc++.h>
using namespace std;
// begin fast read template by CYJian (source: https://www.luogu.com.cn/paste/i11c3ppx)
namespace io {
const int __SIZE = (1 << 21) + 1;
char ibuf[__SIZE], *iS, *iT, obuf[__SIZE], *oS = obuf, *oT = oS + __SIZE - 1, __c, qu[55]; int __f, qr, _eof;
#define Gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
inline void flush () { fwrite (obuf, 1, oS - obuf, stdout), oS = obuf; }
inline void gc (char &x) { x = Gc(); }
inline void pc (char x) { *oS ++ = x; if (oS == oT) flush (); }
inline void pstr (const char *s) { int __len = strlen(s); for (__f = 0; __f < __len; ++__f) pc (s[__f]); }
inline void gstr (char *s) { for(__c = Gc(); __c < 32 || __c > 126 || __c == ' ';) __c = Gc();
for(; __c > 31 && __c < 127 && __c != ' '; ++s, __c = Gc()) *s = __c; *s = 0; }
template <class I> inline bool gi (I &x) { _eof = 0;
for (__f = 1, __c = Gc(); (__c < '0' || __c > '9') && !_eof; __c = Gc()) { if (__c == '-') __f = -1; _eof |= __c == EOF; }
for (x = 0; __c <= '9' && __c >= '0' && !_eof; __c = Gc()) x = x * 10 + (__c & 15), _eof |= __c == EOF; x *= __f; return !_eof; }
template <class I> inline void print (I x) { if (!x) pc ('0'); if (x < 0) pc ('-'), x = -x;
while (x) qu[++ qr] = x % 10 + '0', x /= 10; while (qr) pc (qu[qr --]); }
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
} using io::pc; using io::gc; using io::pstr; using io::gstr; using io::gi; using io::print;
// end fast read template by CYJian
#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, a)
#define rep1(i, a) iter(i, 1, (a)+1)
#define log(a) cerr<<"\033[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"\033[0m"<<endl
#define all(a) a.begin(), a.end()
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using ll=long long;
using pii=pair<int, int>;
//#define int ll
const int MOD = 1000000007;
int pre[1<<20], nxt[1<<20], ar[1<<20], lc[1<<20], ans[1<<20];
constexpr int bsize = 1024;
struct qry {
int l, r, id;
const bool operator<(const qry& o) const {
if(l/bsize!=o.l/bsize)return l/bsize<o.l/bsize;
return (l/bsize%2) ? (r<o.r) : (r>o.r);
}
} qs[1<<20];
signed main() {
ios_base::sync_with_stdio(false); cin.tie(0);
int n; gi(n);
rep1(i, n) pre[i] = 0, nxt[i] = n+1, gi(ar[i]);
rep1(i, n) {
pre[i] = lc[ar[i]];
nxt[lc[ar[i]]] = i;
lc[ar[i]] = i;
}
int m; gi(m);
rep(i, m) qs[i].id = i, gi(qs[i].l), gi(qs[i].r);
int L = 1, R = 1, s1 = 1, s2 = 0, s3 = 0, s4 = 0;
sort(qs, qs+m);
rep(i, m) {
for(; L-4 > qs[i].l; L-=4) {
s1 += (R < nxt[L-1]);
s2 += (R < nxt[L-2]);
s3 += (R < nxt[L-3]);
s4 += (R < nxt[L-4]);
}
for(; L > qs[i].l; L--)
s1 += (R < nxt[L-1]);
for(; R+4 < qs[i].r; R+=4) {
s1 += (pre[R+1] < L);
s2 += (pre[R+2] < L);
s3 += (pre[R+3] < L);
s4 += (pre[R+4] < L);
}
for(; R < qs[i].r; R++)
s1 += (pre[R+1] < L);
for(; L+4 < qs[i].l; L+=4) {
s1 -= (R < nxt[L]);
s2 -= (R < nxt[L+1]);
s3 -= (R < nxt[L+2]);
s4 -= (R < nxt[L+3]);
}
for(; L < qs[i].l; L++)
s1 -= (R < nxt[L]);
for(; R-4 > qs[i].r; R-=4) {
s1 -= (pre[R] < L);
s2 -= (pre[R-1] < L);
s3 -= (pre[R-2] < L);
s4 -= (pre[R-3] < L);
}
for(; R > qs[i].r; R--)
s1 -= (pre[R] < L);
ans[qs[i].id] = s1 + s2 + s3 + s4;
}
rep(i, m) print(ans[i]), pc('\n');
}
// writer: w33z8kqrqk8zzzx33
#include <bits/stdc++.h>
using namespace std;
// begin fast read template by CYJian (source: https://www.luogu.com.cn/paste/i11c3ppx)
namespace io {
const int __SIZE = (1 << 21) + 1;
char ibuf[__SIZE], *iS, *iT, obuf[__SIZE], *oS = obuf, *oT = oS + __SIZE - 1, __c, qu[55]; int __f, qr, _eof;
#define Gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
inline void flush () { fwrite (obuf, 1, oS - obuf, stdout), oS = obuf; }
inline void gc (char &x) { x = Gc(); }
inline void pc (char x) { *oS ++ = x; if (oS == oT) flush (); }
inline void pstr (const char *s) { int __len = strlen(s); for (__f = 0; __f < __len; ++__f) pc (s[__f]); }
inline void gstr (char *s) { for(__c = Gc(); __c < 32 || __c > 126 || __c == ' ';) __c = Gc();
for(; __c > 31 && __c < 127 && __c != ' '; ++s, __c = Gc()) *s = __c; *s = 0; }
template <class I> inline bool gi (I &x) { _eof = 0;
for (__f = 1, __c = Gc(); (__c < '0' || __c > '9') && !_eof; __c = Gc()) { if (__c == '-') __f = -1; _eof |= __c == EOF; }
for (x = 0; __c <= '9' && __c >= '0' && !_eof; __c = Gc()) x = x * 10 + (__c & 15), _eof |= __c == EOF; x *= __f; return !_eof; }
template <class I> inline void print (I x) { if (!x) pc ('0'); if (x < 0) pc ('-'), x = -x;
while (x) qu[++ qr] = x % 10 + '0', x /= 10; while (qr) pc (qu[qr --]); }
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
} using io::pc; using io::gc; using io::pstr; using io::gstr; using io::gi; using io::print;
// end fast read template by CYJian
#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, a)
#define rep1(i, a) iter(i, 1, (a)+1)
#define log(a) cerr<<"\033[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"\033[0m"<<endl
#define all(a) a.begin(), a.end()
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using ll=long long;
using pii=pair<int, int>;
//#define int ll
const int MOD = 1000000007;
int cnt[100005]; ll glbmx=0;
int val[100005];
struct redaction {
int pos, prevcnt; ll prevmx;
}; stack<redaction> re;
void rollback() {
redaction q = re.top(); re.pop();
cnt[q.pos] = q.prevcnt;
glbmx = q.prevmx;
}
constexpr int N=100005;
constexpr int B=300;
int ar[N<<1];
int n;
void ins(int p, bool side) {
int v = ar[p];
re.push({v, cnt[v], glbmx});
if(!(1 <= p <= n)) return;
cnt[v]++; glbmx = max(glbmx, 1ll*val[v]*cnt[v]);
}
ll ans[N];
vector<pair<int,pii>> buccit[100000/B+5];
signed main() {
ios_base::sync_with_stdio(false); cin.tie(0);
map<int,int> lsh;
int q; gi(n), gi(q);
rep1(i, n) {
gi(ar[i]);
if(!lsh.count(ar[i])) {
lsh[ar[i]] = lsh.size()+1;
val[lsh[ar[i]]] = ar[i];
}
ar[i] = lsh[ar[i]];
}
rep(i, q) {
int l, r; gi(l), gi(r);
if((r-l+1)<=B) {
iter(j, l, r+1) ins(j, 1);
ans[i] = glbmx;
while(re.size()) rollback();
} else buccit[r/B].push_back({l, {r, i}});
}
rep(i, n/B+1) {
while(re.size()) rollback();
int cl = i*B, cr = i*B-1;
sort(all(buccit[i]));
reverse(all(buccit[i]));
for(auto q:buccit[i]) {
while(q.fi < cl) ins(--cl, 0);
int ocr = cr;
while(cr < q.se.fi) ins(++cr, 1);
::ans[q.se.se] = glbmx;
// cout << q.se.se << ' ' << i << ' ' << cl << ' ' << cr << ' ' << ca << endl;
while(ocr < cr) rollback(), cr--;
}
}
rep(i, q) print(ans[i]), pc('\n');
}
// writer: w33z8kqrqk8zzzx33
#include <bits/stdc++.h>
using namespace std;
// begin fast read template by CYJian (source: https://www.luogu.com.cn/paste/i11c3ppx)
namespace io {
const int __SIZE = (1 << 21) + 1;
char ibuf[__SIZE], *iS, *iT, obuf[__SIZE], *oS = obuf, *oT = oS + __SIZE - 1, __c, qu[55]; int __f, qr, _eof;
#define Gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, __SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
inline void flush () { fwrite (obuf, 1, oS - obuf, stdout), oS = obuf; }
inline void gc (char &x) { x = Gc(); }
inline void pc (char x) { *oS ++ = x; if (oS == oT) flush (); }
inline void pstr (const char *s) { int __len = strlen(s); for (__f = 0; __f < __len; ++__f) pc (s[__f]); }
inline void gstr (char *s) { for(__c = Gc(); __c < 32 || __c > 126 || __c == ' ';) __c = Gc();
for(; __c > 31 && __c < 127 && __c != ' '; ++s, __c = Gc()) *s = __c; *s = 0; }
template <class I> inline bool gi (I &x) { _eof = 0;
for (__f = 1, __c = Gc(); (__c < '0' || __c > '9') && !_eof; __c = Gc()) { if (__c == '-') __f = -1; _eof |= __c == EOF; }
for (x = 0; __c <= '9' && __c >= '0' && !_eof; __c = Gc()) x = x * 10 + (__c & 15), _eof |= __c == EOF; x *= __f; return !_eof; }
template <class I> inline void print (I x) { if (!x) pc ('0'); if (x < 0) pc ('-'), x = -x;
while (x) qu[++ qr] = x % 10 + '0', x /= 10; while (qr) pc (qu[qr --]); }
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
} using io::pc; using io::gc; using io::pstr; using io::gstr; using io::gi; using io::print;
// end fast read template by CYJian
#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, a)
#define rep1(i, a) iter(i, 1, (a)+1)
#define log(a) cerr<<"\033[32m[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<"\033[0m"<<endl
#define all(a) a.begin(), a.end()
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using ll=long long;
using pii=pair<int, int>;
//#define int ll
const int MOD = 1000000007;
const int B = 316;
int seq[500005];
int fir[500005], sec[500005], clo, clo2;
int bg[500005], en[500005];
int fa[500005][19];
vector<int> elist[500005];
void dfs(int u, int f) {
bg[u] = clo2++;
fir[u] = clo++;
seq[fir[u]]=u;
fa[u][0] = f;
rep1(i, 18) fa[u][i] = fa[fa[u][i-1]][i-1];
for(int v:elist[u]) if(v != f) dfs(v, u);
sec[u] = clo++;
seq[sec[u]]=u;
en[u] = clo2;
}
int lca(int u, int v) {
if(bg[u] <= bg[v] && bg[v] < en[u]) return u;
for(int i=18; i>=0; i--)
if(!(bg[fa[u][i]] <= bg[v] && bg[v] < en[fa[u][i]]))
u = fa[u][i];
return fa[u][0];
}
struct qr {
int l, r, lc, i;
const bool operator<(const qr& o) const {
if(l/B != o.l/B) return l < o.l;
return ((l/B)%2)?(r<o.r):(r>o.r);
}
} qrs[500005];
int res[500005], cnt[500005];
int ar[500005], globans = 0;
bool has[500005];
void tognode(int u) {
if(has[u]) {
cnt[ar[u]]--;
globans -= !cnt[ar[u]];
} else {
globans += !cnt[ar[u]];
cnt[ar[u]]++;
}
has[u] ^= 1;
}
signed main() {
ios_base::sync_with_stdio(false); cin.tie(0);
en[0] = 1e9;
int n, q;
while(cin >> n >> q) {
clo = clo2 = 0;
rep1(i, n) {
elist[i].clear();
fir[i] = sec[i] = 0;
bg[i] = en[i] = 0;
cnt[i] = ar[i] = has[i] = 0;
rep(j, 19) fa[j][i] = 0;
}
rep(i, q+1) {
res[i] = 0;
qrs[i].l = qrs[i].r = qrs[i].lc = 0;
}
map<int,int> lsh;
rep1(i, n) {
cin >> ar[i];
if(!lsh.count(ar[i]))lsh[ar[i]]=lsh.size()+1;
ar[i]=lsh[ar[i]];
}
rep(i, n-1) {
int u, v; cin >> u >> v;
elist[u].pb(v); elist[v].pb(u);
}
dfs(1, 0);
// rep(i, 2*n) cout << seq[i] << " \n"[i==2*n-1];
rep(i, q) {
qrs[i].i = i;
int u, v; cin >> u >> v;
int L = lca(u, v);
if(u != L && v != L) {
qrs[i].lc = L;
if(sec[u] <= fir[v]) qrs[i].l = sec[u], qrs[i].r = fir[v];
else qrs[i].l = sec[v], qrs[i].r = fir[u];
} else {
if(u == L) u = v;
qrs[i].l = fir[L]; qrs[i].r = fir[u];
}
// cout << u << ' ' << v << ' ' << L << endl;
}
sort(qrs, qrs+q);
int cl = 1, cr = 0;
rep(i, q) {
while(cr < qrs[i].r) tognode(seq[++cr]);
while(qrs[i].l < cl) tognode(seq[--cl]);
while(qrs[i].r < cr) tognode(seq[cr--]);
while(cl < qrs[i].l) tognode(seq[cl++]);
res[qrs[i].i] = globans + (qrs[i].lc ? (!cnt[ar[qrs[i].lc]]) : 0);
}
rep(i, q) cout << res[i] << '\n';
}
}
代码仅搬主要部分。
const int MOD = 19260817;
namespace MillerRabin {
int qpow(int b, int e, int m) {
int ans = 1;
while(e) {
if(e & 1) ans = 1ll*ans*b%m;
b = 1ll*b*b%m;
e >>= 1;
}
return ans;
}
bool test(int n) {
if(n<2 || n%6%4 != 1) return (n|1) == 3;
static int ar[4] = {2, 325, 9375, 28178};
int s=__builtin_ctz(n-1); int d=n>>s;
rep(i, 4) {
int k = qpow(ar[i]%n, d, n); int t=s;
while(k!=1 && k!=n-1 && ar[i]%n && t--) k=1ll*k*k%n;
if(t!=s && k!=n-1) return 0;
}
return 1;
}
}
mt19937 rng;
namespace Factor {
set<int> p;
void mxf(int n) {
if(n == 1) return;
if(MillerRabin::test(n)) { p.insert(n); return; }
auto g = [&](int x){ return (1ll*x*x+1)%n; };
int x = 0, y = 1, pd = 2, tk = 0, tmp;
while(++tk % 10 || __gcd(pd, n) == 1) {
if(x == y) x = rng()%n, y = g(x);
if(tmp = 1ll*(max(x, y) - min(x, y))*pd%n) pd = tmp;
x = g(x), y = g(g(y));
}
int d = __gcd(pd, n);
mxf(d), mxf(n/d);
}
}
map<int,int> wkp;
set<int> sm;
int pw[1<<20];
int inv[3<<20];
int a[100005], lef[100005];
int ba[1<<20], ex[1<<20];
const int bs = 316;
struct qr {
int l, r, i;
const bool operator<(const qr& o) const {
if(l/bs != o.l/bs) return l < o.l;
return ((l/bs)%2) ? (r < o.r) : (r > o.r);
}
} qr[100005];
int ans[100005], smp[100005];
int ps[100005];
int th = 88;
inline void add(int id, int& ca) {
int be = lef[id], en = lef[id+1];
iter(p, be, en) ca=1ll*ca*inv[pw[ba[p]]]%MOD*(pw[ba[p]]+=ex[p])%MOD;
}
inline void del(int id, int& ca) {
int be = lef[id], en = lef[id+1];
iter(p, be, en) ca=1ll*ca*inv[pw[ba[p]]]%MOD*(pw[ba[p]]-=ex[p])%MOD;
}
signed main() {
ios_base::sync_with_stdio(false); cin.tie(0);
int n, q; gi(n), gi(q);
inv[0] = inv[1] = 1;
iter(i, 2, n*30+2) inv[i]=1ll*(MOD-MOD/i)*inv[MOD%i]%MOD;
int cn = 0;
rng = mt19937(108616);
rep1(i, n) gi(a[i]);
rep(i, q) gi(qr[i].l), gi(qr[i].r), qr[i].i = i, ans[i] = 1;
rep1(p, th) {
if(!MillerRabin::test(p)) continue;
rep1(i, n) {
ps[i] = ps[i-1];
while(a[i] % p == 0) a[i] /= p, ps[i]++;
}
rep(i, q) ans[i] = 1ll * ans[i] * (ps[qr[i].r] - ps[qr[i].l-1] + 1) % MOD;
}
rep1(i, n) {
Factor::p.clear(); Factor::mxf(a[i]);
int v = a[i];
lef[i] = cn;
for(int p:Factor::p) {
if(!wkp.count(p)) wkp[p] = wkp.size();
ba[cn] = wkp[p];
pw[ba[cn]] = 1;
while(v % p == 0) v /= p, ex[cn]++;
cn++;
}
}
lef[n+1] = cn;
sort(qr, qr+q);
int ca = 1, l = 1, r = 0;
rep(i, q) {
while(r < qr[i].r) add(++r, ca);
while(qr[i].l < l) add(--l, ca);
while(qr[i].r < r) del(r--, ca);
while(l < qr[i].l) del(l++, ca);
ans[qr[i].i] = 1ll * ans[qr[i].i] * ca % MOD;
}
rep(i, q) print(ans[i]), pc('\n');
}
代码仅搬主要部分。
FastMod 是一个快速摸工具。
const int bs = 317;
struct q {
int l, r, p, i;
const bool operator<(const q& o) const {
if(l/bs != o.l/bs) return l < o.l;
return ((l/bs)%2) ? (r < o.r) : (r > o.r);
}
} qr[100005];
int ar[100005], re[100005];
uint64_t vv[100100>>6];
template<typename T>
void process(int wds, T func) {
rep(i, wds) {
if(!vv[i]) continue;
uint64_t cp = vv[i];
while(cp) {
int pos = __builtin_ctzll(cp);
func(i*64|pos);
cp ^= (1ull << pos);
}
}
}
ll mt[100005];
int coun[100005];
int lo[bs+1], hi[bs];
#define rem(aede) { mt[coun[aede]] -= aede; vv[coun[aede]>>6] ^= ((mt[coun[aede]]) ? 0 : (1ull<<(coun[aede]&63))); }
#define ic(aede) { vv[coun[aede]>>6] |= (1ull<<(coun[aede]&63)); mt[coun[aede]] += aede; }
signed main() {
ios_base::sync_with_stdio(false); cin.tie(0);
int n, q; gi(n), gi(q);
rep1(i, n) gi(ar[i]);
rep(i, q) gi(qr[i].l), gi(qr[i].r), gi(qr[i].p), qr[i].i = i;
int cl = 1, cr = 0;
sort(qr, qr+q);
mt[0] = 100000ll*100001/2;
vv[0] = 1;
rep(i, q) {
while(cr < qr[i].r) {
int ad = ar[++cr];
rem(ad); coun[ad]++; ic(ad);
}
while(qr[i].l < cl) {
int ad = ar[--cl];
rem(ad); coun[ad]++; ic(ad);
}
while(qr[i].r < cr) {
int re = ar[cr--];
rem(re); coun[re]--; ic(re);
}
while(cl < qr[i].l) {
int re = ar[cl++];
rem(re); coun[re]--; ic(re);
}
int L = cr - cl + 1;
int p = qr[i].p, ans = 0;
lo[0] = 1;
FastMod F(p);
rep1(i, bs) {
lo[i] = lo[i-1]<<1;
lo[i] -= (lo[i] >= p ? p : 0);
}
hi[0] = 1; hi[1] = lo[bs];
iter(i, 2, bs) hi[i] = F.reduce(1ll*hi[1]*hi[i-1]);
process((L>>6)+1, [&](int i){
ans = F.reduce(ans + F.reduce(1ll * F.reduce(mt[i]) * lo[(L-i)%bs]) * hi[(L-i)/bs]);
});
ll v = 100000ll*100001/2;
v %= p; v = v * lo[L%bs] % p * hi[L/bs] % p;
re[qr[i].i] = (v + p - ans) % p;
}
rep(i, q) print(re[i]), pc('\n');
}