2019 cattle off more school fourth solution to a problem

2019 cattle off more school fourth solution to a problem

Topic Link

A.meeting

Keys disposed farthest distance \ (D \) , the answer is \ (\ lceil \ FRAC} {2} {D \ rceil \) .
Directly for root casually dp is required. .


Code

#include <bits/stdc++.h>
using namespace std;
 
const int maxn = 1e5+10;
vector<int>g[maxn];
int vis[maxn];
int len,st,ed;
void dfs(int u,int fa,int dep){
    if(vis[u]){
        if(dep>len){
            len=dep;
            ed=u;
        }
    }
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==fa)continue;
        dfs(v,u,dep+1);
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,k;
    cin>>n>>k;
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v),g[v].push_back(u);
    }
    for(int i=1;i<=k;i++){
        cin>>st;
        vis[st]=1;
    }
    len=1,ed=st;
    dfs(st,0,1);
    st=ed;
    dfs(st,0,1);
    cout<<len/2<<endl;
}

B.xor

Group is said to be linear board post title, but still has a large wave A the gods. .
Intersection of two groups, then probably set to \ (Bl, B2 \) , enumeration \ (B2 \) in the base, and if \ (Bl \) linearly independent, then inserted in the \ (Bl \) to go inside ; otherwise for the current group, isobutyl or off \ (Bl \) insert before the (B2 \) \ base, and then inserted inside the intersection of the line. Proof, then we can look at the blog: Portal


Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const int N = 50005;
int n, m;
struct node{
    ui r[32], f[32];
    bool ins(ui x) {
        for(int i = 31; i >= 0; i--) {
            if(x >> i) {
                if(!r[i]) {r[i] = x; return 1;}
                else x ^= r[i];
            }
        }
        return 0;
    }
    bool ins2(ui x) {
        ui tmp = x;
        for(int i = 31; i >= 0; i--) {
            if(x >> i) {
                if(!r[i]) {r[i] = x; f[i] = tmp; return 1;}
                else {
                    x ^= r[i]; tmp ^= f[i];
                }
            }
        }
        return 0;
    }
    void clear() {
        for(int i = 0; i <= 31; i++) r[i] = f[i] = 0;
    }
    bool find(ui x) {
        for(int i = 31; i >= 0; i--) {
            if(x >> i) {
                if(!r[i]) return 0;
                x ^= r[i];
            }
        }
        return x == 0;
    }
    int calc(ui x) {
        int ans = 0;
        for(int i = 31; i >= 0; i--) {
            if(x >> i) {
                x ^= r[i];
                ans ^= f[i];
            }
        }
        return ans;
    }
};
node _merge(node u, node v) {
    node tmp, res; res.clear();
    tmp = u;
    for(int i = 31; i >= 0; i--) {
        ui x = v.r[i];
        if(tmp.find(x)) {
            res.ins(x ^ tmp.calc(x));
        } else tmp.ins2(x);
    }
    return res;
}
ui a[N][33];
node b[N << 2];
void build(int o, int l, int r) {
    if(l == r) {
        b[o].clear();
        for(int j = 1; j <= 32; j++) b[o].ins(a[l][j]);
        return ;
    }
    int mid = (l + r) >> 1;
    build(o << 1, l, mid); build(o << 1|1, mid + 1, r);
    b[o] = _merge(b[o << 1], b[o << 1|1]);
}
bool query(int o, int l, int r, int L, int R, ui v) {
    if(L <= l && r <= R) {
        return b[o].find(v);
    }
    int mid = (l + r) >> 1;
    bool ans = 1;
    if(L <= mid) ans &= query(o << 1, l, mid, L, R, v);
    if(R > mid) ans &= query(o << 1|1, mid + 1, r, L, R, v) ;
    return ans;
}
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        int k; cin >> k;
        for(int j = 1; j <= k; j++) cin >> a[i][j];
    }
    build(1, 1, n);
    for(int i = 1, l, r; i <= m; i++) {
        ui x; cin >> l >> r >> x;
        if(query(1, 1, n, l, r, x)) cout << "YES" << '\n';
        else cout << "NO" << '\n';
    }
    return 0;
}

C.sequence

Nanchang network race out too monotonous + stack segment tree maintenance on the line.


Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ld;
const int MAXN = 3e6 + 5, MAXM = 2e4 + 5, BOUND = 2e5 + 5, MOD = 1e9 + 7, INF = 0x3f3f3f3f, base = 10000;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0), eps = 1e-9;
#define mid l + ((r-l)>>1)
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define lc(x) ch[x][0]
#define pii pair<int,int>
#define vi vector<int>
#define RR register int
#define rc(x) ch[x][1]
#define rep(i,a,b) for(RR i=(a);i<=(b);++i)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
struct Istream {
    template <class T>
    Istream &operator >>(T &x) {
        static char ch; static bool neg;
        for (ch = neg = 0; ch < '0' || '9' < ch; neg |= ch == '-', ch = getchar());
        for (x = 0; '0' <= ch && ch <= '9'; (x *= 10) += ch - '0', ch = getchar());
        x = neg ? -x : x;
        return *this;
    }
}fin;
 
struct Ostream {
    template <class T>
    Ostream &operator <<(T x) {
        x < 0 && (putchar('-'), x = -x);
        static char stack[233]; static int top;
        for (top = 0; x; stack[++top] = x % 10 + '0', x /= 10);
        for (top == 0 && (stack[top = 1] = '0'); top; putchar(stack[top--]));
        return *this;
    }
 
    Ostream &operator <<(char ch) {
        putchar(ch);
        return *this;
    }
}fout;
int n, a[MAXN], b[MAXN], l1[MAXN], r1[MAXN], st[MAXN], top = 0;
ll maxv[MAXN << 2][2], minv[MAXN << 2][2], s[MAXN], s2[MAXN];
inline void pushUp(int o) {
    rep(i, 0, 1) {
        maxv[o][i] = max(maxv[o << 1][i], maxv[o << 1 | 1][i]);
        minv[o][i] = min(minv[o << 1][i], minv[o << 1 | 1][i]);
    }
}
void build(int o, int l, int r) {
    if (l == r) {
        maxv[o][0] = minv[o][0] = s[l];
        maxv[o][1] = minv[o][1] = s2[l];
        return;
    }
    int m = mid;
    build(lson); build(rson);
    pushUp(o);
}
ll query(int o, int l, int r, int L, int R, int t, int t2) {
    if (l >= L && r <= R) {
        if (t == 0)return minv[o][t2];
        else return maxv[o][t2];
    }
    int m = mid;
    ll ans;
    if (t == 0) {
        ans = INFL;
        if (L <= m)ans = min(ans, query(lson, L, R, t, t2));
        if (R > m)ans = min(ans, query(rson, L, R, t, t2));
    }
    else {
        ans = -INFL;
        if (L <= m)ans = max(ans, query(lson, L, R, t, t2));
        if (R > m)ans = max(ans, query(rson, L, R, t, t2));
    }
    return ans;
}
int main() {
    //ios::sync_with_stdio(false); cin.tie(0);
    fin >> n;
    rep(i, 1, n)fin >> a[i];
    rep(i, 1, n)fin >> b[i];
    rep(i, 1, n)s[i] = s[i - 1] + b[i];
    for (int i = n; i >= 1; i--)s2[i] = s2[i + 1] + b[i];
    build(1, 0, n + 1);
    // 左边第一个比当前小
    st[0] = 0;
    rep(i, 1, n) {
        while (top &&a[st[top]] >= a[i])top--;
        l1[i] = st[top];
        st[++top] = i;
    }
    st[0] = n + 1;
    top = 0;
    // 右边第一个比当前小
    for (int i = n; i >= 1; i--) {
        while (top &&a[st[top]] >= a[i])top--;
        r1[i] = st[top];
        st[++top] = i;
    }
    ll ans = -INFL;
    rep(i, 1, n) {
        if (a[i] > 0) {
            ll tmp = a[i] * (s[i] - query(1, 0, n + 1, l1[i], i, 0, 0) +
                s2[i] - query(1, 0, n + 1, i, r1[i], 0, 1) - b[i]);
            //printf("%d %lld %lld %lld\n", i, query(1, 0, n + 1, l1[i], i, 0, 0), query(1, 0, n + 1, i, r1[i], 0, 1), (s[i] - query(1, 0, n + 1, l1[i], i, 0, 0) +
            //s2[i] - query(1, 0, n + 1, i, r1[i], 0, 1) - a[i]));
            ans = max(ans, tmp);
        }
        else {
            ll tmp = a[i] * (s[i] - query(1, 0, n + 1, l1[i], i, 1, 0) +
                s2[i] - query(1, 0, n + 1, i, r1[i], 1, 1) - b[i]);
            //printf("%d %lld %lld %lld\n", i, query(1, 0, n + 1, l1[i], i, 0, 0), query(1, 0, n + 1, i, r1[i], 0, 1), (s[i] - query(1, 0, n + 1, l1[i], i, 0, 0) +
            //s2[i] - query(1, 0, n + 1, i, r1[i], 0, 1) - a[i]));
            ans = max(ans, tmp);
        }
    }
    cout << ans << '\n';
    return 0;
}

D.triples I

This problem may be to think above each bin, would find such a formula: \ (X ^ 2 \) % (! = 0. 3 \) \ , and for a valid \ (A \) , whose binary The number of no less than \ (3 \) .
Because the modulus is 3, so the discussion can be divided.
When \ (A \) % \ (. 3 = 0 \) , the answer is clearly a;
when the \ (A \) % \ (. 3 =. 1 \) holds, the above \ (2 ^ X \) % \ (. 3 ! = 0 \) known per bit mode \ (3 \) is either 1 or 2, and \ (a \) all the bits together, then it depends on multiple Couchu 3 related binary the number.
So we discuss further classified: remember \ (cnt_i \) denotes a binary bit modulo 3 is equal to \ (I \) number. After this classification talk about on the line.
Refer to code it:


Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 64;
ll a;
int T;
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> T;
    while(T--) {
        cin >> a;
        if(a % 3 == 0) {
            cout << 1 << ' ' << a << '\n';
            continue;
        }
        cout << 2 << ' ' ;
        vector <int> v1, v2;
        for(int i = 0; i < N; i++) {
            if(!(a >> i & 1)) continue;
            if((1LL << i) % 3 == 1) v1.push_back(i);
            else v2.push_back(i);
        }
        if(a % 3 == 1) {
            if((int)(v1.size()) >= 2) {
                cout << a - (1LL << v1[0]) << ' ' << a - (1LL << v1[1]) << '\n';
            } else if((int)v1.size() == 1) {
                cout << a - (1LL << v1[0]) << ' ' << (1LL << v1[0]) + (1LL << v2[0]) << '\n';
            } else {
                cout << (1LL << v2[0]) + (1LL << v2[1]) + (1LL << v2[2])<< ' ' << a - (1LL << v2[0]) - (1LL << v2[1]) << '\n';
            }
        } else {
            if((int)(v2.size()) >= 2) {
                cout << a - (1LL << v2[0]) << ' ' << a - (1LL << v2[1]) << '\n';
            } else if((int)v2.size() == 1) {
                cout << a - (1LL << v2[0]) << ' ' << (1LL << v2[0]) + (1LL << v1[0]) << '\n';
            } else {
                cout << (1LL << v1[0]) + (1LL << v1[1]) + (1LL << v1[2])<< ' ' << a - (1LL << v1[0]) - (1LL << v1[1]) << '\n';
            }
        }
    }
    return 0;
}

I.string

For a string, if exist \ (A \) and \ (Rev (A) \) , the essence of our just different substring, they will be counted twice, and the remaining without \ (Rev \) of it will be counted only once.
But the title \ (a \) and \ (rev (a) \) can only be counted once. However, if observed playing back a splice, then \ (A \) and \ (rev (a) \) is likewise calculated twice, while the rest will be counted twice, except palindromic sequence.
So we need to do is get with the suffix array string after the splicing of different nature, but not the middle mosaic character, is set to \ (the p-\) ; additional consideration palindrome string will only be counted once, so together with string back number of text strings \ (Q \) . Then the final answer is \ (\ FRAC P + Q {} {2} \) .
code show as below:


Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5 + 5;
char s[N];
namespace SA{                                       //sa:1...n  Rank:0...n-1
    int x[N], y[N], sa[N], c[N], height[N], Rank[N];
    int f[N][20], lg[N];
    int n;                                          //length
    void da(char *s, int m){
        n++;
        for(int i = 0; i < m; i++) c[i] = 0;
        for(int i = 0; i < n; i++) c[x[i] = s[i]]++;
        for(int i = 1; i < m; i++) c[i] += c[i - 1] ;
        for(int i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
        for(int k = 1; k <= n; k <<= 1) {
            int p = 0 ;
            for(int i = n - k; i < n; i++) y[p++] = i ;
            for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] =sa[i] - k;
            for(int i = 0; i < m; i++) c[i] = 0;
            for(int i = 0; i < n; i++) c[x[y[i]]]++;
            for(int i = 1; i < m; i++) c[i] += c[i - 1];
            for(int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i] ;
            swap(x , y); p = 1; x[sa[0]] = 0;
            for(int i = 1; i < n; i++)
                x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i-1] + k] == y[sa[i] + k] ? p - 1 : p++;
            if(p >= n) break ;
            m = p;
        }
        n--;
        int k = 0;
        for(int i = 0; i <= n; i++) Rank[sa[i]] = i;
        for(int i = 0; i < n; i++) {
            if(k) k--;
            int j = sa[Rank[i] - 1];
            while(s[i + k] == s[j + k]) k++;
            height[Rank[i]] = k;
        }
    }
    ll count() {
        ll ans = 0;
        for(int i = 1; i <= n; i++) ans += n - sa[i] - height[i];
        return ans;
    }
    void init() {
        for(int i = 2; i < N; i++) lg[i] = lg[i >> 1] + 1;
        for(int i = 2; i <= n; i++) f[i][0] = height[i];
        for(int j = 1; j < 20; j++)
            for(int i = 2; i + (1 << j) - 1 <= n; i++)
                f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]) ;
    }
    int get_lcp(int l, int r) {
        if(Rank[l] > Rank[r]) swap(l, r);
        l = Rank[l] + 1, r = Rank[r];
        int k = lg[r - l + 1];
        return min(f[l][k], f[r - (1 << k) + 1][k]);
    }
}
namespace PAM{
    int ch[N][26], fail[N], len[N], st[N], cnt[N];
    int sz, n, last;
    int New(int l, int f) {
        memset(ch[++sz], 0, sizeof(ch[sz]));
        len[sz] = l, fail[sz] = f;
        return sz;
    }
    void init() {
        sz = -1;
        New(0, 1); last = New(-1, 0);
        st[n = 0] = -1;
        memset(cnt, 0, sizeof(cnt));
    }
    int getf(int x) {
        while(st[n - len[x] - 1] != st[n]) x = fail[x];
        return x;
    }
    bool Insert(int c) { //int
        st[++n] = c;
        int x = getf(last);
        bool F = 0;
        if(!ch[x][c]) {
            F = 1;
            int f = getf(fail[x]);
            ch[x][c] = New(len[x] + 2, ch[f][c]);
        }
        last = ch[x][c];
        cnt[last] = 1;
        return F;
    }
    void count() {
        for(int i = sz; i >= 1; i--) cnt[fail[i]] += cnt[i];
    }
};
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> s;
    int n = strlen(s);
    ll ans = 0;
    PAM::init();
    for(int i = 0; i < n; i++) PAM::Insert(s[i] - 'a');
    for(int i = 1; i <= PAM::sz; i++) ans += PAM::cnt[i];
    s[n] = '&';
    for(int i = n + 1; i <= 2 * n; i++) s[i] = s[2 * n - i];
    s[n * 2 + 1] = '\0';
    SA::n = 2 * n + 1;
    SA::da(s, 520);
    ans += SA::count();
    ans -= 1ll * (n + 1) * (n + 1);
    cout << ans / 2;
    return 0;
}

J.free

dijkstra direct two-dimensional state run on the line, when the transfer is similar to dp so, consider whether the current free here. I zz enumeration on the test a little, but fortunately less data, or GG.


Code

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
int n, m, S, T, k;
struct edge{
    int u, v, w;
    bool operator < (const edge &A)const {
        return w < A.w;
    }
}E[N];
struct Edge{
    int u,v,w,next ;
}e[N << 1];
int tot, head[N];
int W[N][N];
struct node{
    int d, u, c;
    bool operator < (const node &A)const{
        return d>A.d;
    }
};
void adde(int u,int v,int w){
    e[tot].v=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot++;
}
int d[N];
bool vis[N];
bool Dijkstra(int s){
    priority_queue <node> q; memset(d,INF,sizeof(d));
    memset(vis,0,sizeof(vis));d[s]=0;
    q.push(node{0, s, 0});
    while(!q.empty()){
        node cur = q.top();q.pop();
        int u=cur.u;
        vis[u]=1;
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(d[v]>d[u]+e[i].w && cur.c + (e[i].w == 0) <= k){
                d[v]=d[u]+e[i].w;
                q.push(node{d[v],v, cur.c + (e[i].w == 0)});
            }
        }
    }
    return d[T] != INF;
}
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n >> m >> S >> T >> k;
    int tmp = 0;
    for(int i = 1; i <= m; i++) {
        int u, v, w; cin >> u >> v >> w;
        if(u == v) continue;
        if(u > v) swap(u, v);
        if(W[u][v]) W[u][v] = min(W[u][v], w);
        else W[u][v] = w;
    }
    for(int i = 1; i <= n; i++)
        for(int j = i + 1; j <= n; j++)
            if(W[i][j]) E[++tmp] = edge{i, j ,W[i][j]};
    m = tmp;
    sort(E + 1, E + m + 1);
    int ans = INF;
    for(int i = m; i >= 1; i--) {
        memset(head, -1, sizeof(head)); tot = 0;
        for(int j = i; j <= m; j++) {
            adde(E[j].u, E[j].v, 0);
            adde(E[j].v, E[j].u, 0);
        }
        for(int j = 1; j < i; j++) {
            adde(E[j].u, E[j].v, E[j].w);
            adde(E[j].v, E[j].u, E[j].w);
        }
        if(Dijkstra(S)) ans = min(ans, d[T]);
    }
    cout << ans << '\n';
    return 0;
}

K.number

Attendance problems, dp or maintenance Prefix mold 3 can do.


Code

#include<bits/stdc++.h>
typedef long long ll;
const int MAXN = 1e5 + 5, MAXM = 1e5 + 5, INF = 0x3f3f3f3f, MOD = 998244353;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
using namespace std;
const int oo = (1e9) - (1e6);
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pb push_back
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define all(v) (v.begin(),v.end())
typedef long double db;
 
char s[MAXN];
int n, cnt[MAXN], pre[MAXN];
int main() {
    cin >> (s + 1);
    n = strlen(s + 1);
    int sum = 0;
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        sum = (sum * 10 + s[i] - '0') % 300;
        if ((sum - pre[i - 1] * 10 % 300 + 300) % 300 == 0)ans++;
        if (sum == 100)ans += cnt[1];
        else if (sum == 200)ans += cnt[2];
        else if (sum == 0)ans += cnt[0];
        if (i - 1 >= 0)cnt[pre[i - 1] % 3]++;
        pre[i] = sum;
    }
    cout << ans << '\n';
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/11269783.html