国庆のsurprise
在雨中把伞放下,就辨不出脸上是雨水还是泪水;独自穿梭,一任悲伤逆流成河……湿透的衣衫和湿透的梦想,哪个更凉凉?
今天中午回宿舍的路上,你看到那个拎着伞淋雨的少女了吗?
多少无知罪愆,事过不境迁
永志不忘纪念,往事不如烟
没什么,只是又考挂了而已……
A. Rubyonly is always here
听了一下另一种做法的各种奇妙化简,我还是选择了感性理解……于是还是按题解鹤了**

表示为(a, 1-a)中的a是已经除过sum的a,于是发现不知道怎么判断取模之后还在这个区间内,如果取模后l > r的话,判断条件应该是c > l || c < r 。
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 3;
//const ll mod = 1e9 + 7;
const ll inf = 1e13;
ll mod, q, a, b, c, d, sum;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll qpow(ll a, ll b)
{
ll ans = 1;
while(b)
{
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
int main()
{
mod = read(); q = read();
while(q--)
{
a = read(); b = read(); c = read(); d = read();
if((a+b)%mod != (c+d)%mod) {printf("-1\n"); continue;}
sum = (a + b) % mod;
a = a * qpow(sum, mod-2) % mod; c = c * qpow(sum, mod-2) % mod;
for(ll k=0; k<=100; k++)
{
ll x = 1ll << k;
ll l = x * a - (x - 1), r = x * a;
ll len = r - l + 1;
l %= mod; l = (l + mod) % mod;
r %= mod; r = (r + mod) % mod;
if(len >= mod || (l <= r && c >= l && c <= r) || (l > r && (c >= l || c <= r)))
{
printf("%lld\n", k); break;
}
}
}
return 0;
}
B. Su_Zipei is always here
我场上写了个莫队套树状数组然后TLE 30!?还不如暴力呢??
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 3;
const ll mod = 1e9 + 7;
const ll inf = 1e13;
int n, Q, opt, a[maxn], ct[maxn], c[maxn], ans[maxn], sz;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
struct node
{
int l, r, k, id;
bool operator < (const node &T) const
{
return l/sz==T.l/sz ? r<T.r : l<T.l;
}
}q[maxn];
inline int lowbit(int x) {return x & -x;}
inline void upd(int x, int val)
{
while(x <= n)
{
c[x] += val;
x += lowbit(x);
}
}
inline int query(int x)
{
int ans = 0;
while(x)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
inline void add(int x)
{
if(ct[x] != 0) upd(ct[x], -1);
ct[x]++;
upd(ct[x], 1);
}
inline void del(int x)
{
upd(ct[x], -1);
ct[x]--;
if(ct[x] != 0) upd(ct[x], 1);
}
int main()
{
n = read(); Q = read(); opt = read();
for(int i=1; i<=n; i++) a[i] = read();
if(opt == 0)
{
sz = sqrt(n);
for(int i=1; i<=Q; i++)
{
q[i].l = read(); q[i].r = read(); q[i].k = read();
if(q[i].l > q[i].r) swap(q[i].l, q[i].r);
q[i].id = i;
}
sort(q+1, q+1+Q);
for(int i=q[1].l; i<=q[1].r; i++)
{
add(a[i]);
}
int k = q[1].k;
if(k == 1) ans[q[1].id] = query(n);
else ans[q[1].id] = query(n)-query(k-1);
int l = q[1].l, r = q[1].r;
for(int i=2; i<=Q; i++)
{
k = q[i].k;
while(r < q[i].r) add(a[++r]);
while(l > q[i].l) add(a[--l]);
while(l < q[i].l) del(a[l++]);
while(r > q[i].r) del(a[r--]);
if(k == 1) ans[q[i].id] = query(n);
else ans[q[i].id] = query(n)-query(k-1);
}
for(int i=1; i<=Q; i++)
{
printf("%d\n", ans[i]);
}
exit(0);
}
return 0;
}
50分的做法都要鹤:
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 3;
const ll mod = 1e9 + 7;
const ll inf = 1e13;
int n, q, opt, a[maxn], sum[maxn][300], ans, cnt[maxn], mx;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
void solve1()
{
for(int i=1; i<=q; i++)
{
int l = read(), r = read(), k = read();
l = (l + ans*opt - 1) % n + 1;
r = (r + ans*opt - 1) % n + 1;
if(l > r) swap(l, r);
k = (k + ans*opt - 1) % n + 1;
ans = 0;
for(int i=l; i<=r; i++)
{
cnt[a[i]]++;
if(cnt[a[i]] == k) ans++;
}
for(int i=l; i<=r; i++) cnt[a[i]]--;
printf("%d\n", ans);
}
}
void solve2()
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=mx; j++) sum[i][j] = sum[i-1][j];
sum[i][a[i]]++;
}
for(int i=1; i<=q; i++)
{
int l = read(), r = read(), k = read();
l = (l + ans*opt - 1) % n + 1;
r = (r + ans*opt - 1) % n + 1;
if(l > r) swap(l, r);
k = (k + ans*opt - 1) % n + 1;
ans = 0;
for(int j=1; j<=mx; j++) if(sum[r][j]-sum[l-1][j] >= k) ans++;
printf("%d\n", ans);
}
}
int main()
{
n = read(); q = read(); opt = read();
for(int i=1; i<=n; i++) a[i] = read();
if(n <= 1000)
{
solve1(); exit(0);
}
for(int i=1; i<=n; i++) mx = max(a[i], mx);
if(mx <= 300)
{
solve2(); exit(0);
}
return 0;
}
可以直接分块做,似乎需要卡常 %%%Chen_jr
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 3;
const ll mod = 1e9 + 7;
const ll inf = 1e13;
int len = 3300;
int block, n, q, opt, a[maxn], cnt[32][maxn], ans, t[maxn], out[32];
int sum[32][32][maxn];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
void print(int x)
{
int top = 0;
while(x) {out[++top] = x % 10; x /= 10;} if(top == 0) out[++top] = 0;
for(int i=top; i>0; i--) putchar('0'+out[i]);
putchar('\n');
}
int main()
{
n = read(); q = read(); opt = read();
for(int i=1; i<=n; i++) a[i] = read();
block = (n + len - 1) / len;
for(int i=1; i<=block; i++)
{
int l = (i-1)*len+1, r = min(n, i*len);
for(int j=1; j<=n; j++) cnt[i][j] += cnt[i-1][j];
for(int j=l; j<=r; j++) cnt[i][a[j]]++;
}
for(int l=1; l<=block; l++)
{
for(int r=l; r<=block; r++)
{
for(int i=1; i<=n; i++) sum[l][r][cnt[r][i]-cnt[l-1][i]]++;
for(int i=1; i<=n; i++) sum[l][r][i] += sum[l][r][i-1];
}
}
int ans = 0;
while(q--)
{
int l = read(), r = read(), k = read();
l = (l + ans*opt - 1) % n + 1;
r = (r + ans*opt - 1) % n + 1;
if(l > r) swap(l, r);
k = (k + ans*opt - 1) % n + 1;
int bl = (l+len-1)/len, br = (r+len-1)/len;
ans = 0;
if(br-bl <= 1)
{
for(int i=l; i<=r; i++) {t[a[i]]++; ans += t[a[i]] == k;}
for(int i=l; i<=r; i++) t[a[i]] = 0;
print(ans);
continue;
}
ans = sum[bl+1][br-1][n]-sum[bl+1][br-1][k-1];
int liml = bl*len, limr = (br-1)*len+1;
for(int i=l; i<=liml; i++) {t[a[i]]++; ans += t[a[i]]+cnt[br-1][a[i]]-cnt[bl][a[i]]==k;}
for(int i=limr; i<=r; i++) {t[a[i]]++; ans += t[a[i]]+cnt[br-1][a[i]]-cnt[bl][a[i]]==k;}
for(int i=l; i<=liml; i++) t[a[i]] = 0;
for(int i=limr; i<=r; i++) t[a[i]] = 0;
print(ans);
}
return 0;
}
正解还没改qwq
暂且咕了,先完结博客吧
C. Kaiser_Kell is always here
这是第几次错题不会??最主要的是根本没印象……【自然数】
第二问的求法:先把[1, i] 的mex放到线段树上,考虑删掉左边一个点a[i]的影响,就是i之后到下一个a[i]出现之前的mex如果大于a[i]就会被更新成a[i]。区间修改,单点查询,有pushdown没有pushup。
第一问的求法:在一段区间内mex单调不降,修改mex的结果要么是不变要么是等于a[i],如果可以修改为a[i](a[i]有机会成为一段区间的mex),那么修改区间的上界(nxt[i]-1)一定会被修改,所以只需要查询nxt[i]-1就可以了。
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 2;
const ll mod = 1e9 + 7;
const ll inf = 0x3f3f3f3f;
int n, a[maxn], ans[maxn], Q, nxt[maxn], pos[maxn], mex[maxn];
bool vis[maxn];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
struct fairy
{
int l, r, id;
bool operator < (const fairy &T) const
{
return l < T.l;
}
}q[maxn];
struct SegmentTree
{
struct node
{
int val, tag;
}t[maxn<<2];
void build(int x, int l, int r)
{
t[x].tag = inf;
if(l == r)
{
t[x].val = mex[l];
return;
}
int mid = (l + r) >> 1;
build(x<<1, l, mid);
build(x<<1|1, mid+1, r);
}
void pushdown(int x)
{
int ls = x<<1, rs = x<<1|1;
t[ls].val = min(t[ls].val, t[x].tag);
t[ls].tag = min(t[ls].tag, t[x].tag);
t[rs].val = min(t[rs].val, t[x].tag);
t[rs].tag = min(t[rs].tag, t[x].tag);
t[x].tag = inf;
}
void modify(int x, int l, int r, int L, int R, int val)
{
if(L > R) return;
if(L <= l && r <= R)
{
t[x].val = min(t[x].val, val);
t[x].tag = min(t[x].tag, val);
return;
}
if(t[x].tag != inf) pushdown(x);
int mid = (l + r) >> 1;
if(L <= mid) modify(x<<1, l, mid, L, R, val);
if(R > mid) modify(x<<1|1, mid+1, r, L, R, val);
}
int query(int x, int l, int r, int pos)
{
if(l == r) return t[x].val;
if(t[x].tag != inf) pushdown(x);
int mid = (l + r) >> 1;
if(pos <= mid) return query(x<<1, l, mid, pos);
else return query(x<<1|1, mid+1, r, pos);
}
}t;
int main()
{
n = read();
for(int i=1; i<=n; i++) a[i] = read();
Q = read();
for(int i=1; i<=Q; i++)
{
q[i].l = read(); q[i].r = read();
q[i].id = i;
}
sort(q+1, q+1+Q);
int mn = 1;
for(int i=1; i<=n; i++)
{
vis[a[i]] = 1;
while(vis[mn]) mn++;
mex[i] = mn;
}
t.build(1, 1, n);
for(int i=1; i<=n; i++) vis[i] = 0;
for(int i=1; i<=n; i++) vis[mex[i]] = 1;
for(int i=1; i<=n; i++) pos[a[i]] = n+1;
for(int i=n; i>=1; i--)
{
nxt[i] = pos[a[i]];
pos[a[i]] = i;
}
int p = 1;
for(int i=1; i<=n; i++)
{
while(p<=Q && q[p].l == i)
{
ans[q[p].id] = t.query(1, 1, n, q[p].r);
p++;
}
t.modify(1, 1, n, i+1, nxt[i]-1, a[i]);
vis[t.query(1, 1, n, nxt[i]-1)] = 1;
}
mn = 1;
while(vis[mn]) mn++;
printf("%d\n", mn);
for(int i=1; i<=Q; i++)
{
printf("%d ", ans[i]);
}
return 0;
}
D. Pl_er is always here
什么??求导??我可以不会吗……***
时光花火,水月星辰

浙公网安备 33010602011771号