国庆の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

什么??求导??我可以不会吗……***

posted @ 2022-10-01 18:27  Catherine_leah  阅读(24)  评论(1编辑  收藏  举报
/* */