8.7 Round 2

 Just finished the day thinking of the weak, the evening came thinking three questions ...

T1:https://www.luogu.org/problem/T92604

The law did not find out, 35pts roll rough play table

Can be shown (not I), p = a ^ 3 + 3a + 1

When a = 871, p> 2e9, therefore enumerated a, and sqrt (L) determination whether p is a prime number can be

 

T2:https://www.luogu.org/problem/T92605

Thought for a moment on the test, that sum is not good maintenance, so it is violent ...

Title to the y = -1 or 1, ensures that, for a number of modifications, it will only affect around one of the sum

Practice: Statistical SUM [i]: number of values ​​<= i and, [i] num, = number of values ​​of i and

Then, for a number, it can not be deleted, if and only if the num [i]! = 0 && sum [i]! = I

Remember the answer to the above is ok [i], the sequence segment tree maintenance, so we get a weight tree line, the value of 0/1

For inquiries, asking the equivalent of 1-x 1 rightmost position, easy to maintain

For the modification, consider several cases on the line

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<climits>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
#define O(x) cout << #x << " " << x << endl;
#define B cout << "breakpoint" << endl;
#define clr(a) memset(a,0,sizeof(a));
inline int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        (ans *= 10) += ch - '0';
        ch = getchar();
    }
    return ans * op;
}
const int maxn = 5e5 + 5;
int a[maxn],n,m,tp[maxn];
int num[maxn],sum[maxn];
bool ok[maxn];
struct node
{
    int sum,rm;
};
struct seg_tr
{
    node tr[maxn << 2];
    #define ls i << 1
    #define rs i << 1 | 1
    inline node up(node i,node l,node r)
    {
        i.sum = l.sum + r.sum;
        if(r.rm) i.rm = r.rm; else i.rm = l.rm;
        return i;
    }
    void build(int i,int l,int r)
    {
        if(l == r)
        {
            if(ok[l]) tr[i] = (node){1,l};
            else tr[i] = (node){0,0};
            return;
        }
        int mid = l + r >> 1;
        build(ls,l,mid);
        build(rs,mid + 1,r);
        tr[i] = up(tr[i],tr[ls],tr[rs]);
    }
    void change(int i,int l,int r,int x,int d)
    {
        if(l == r)
        {
            tr[i].sum = d;
            if(d) tr[i].rm = l;
            else tr[i].rm = 0;
            return;
        }
        int mid = l + r >> 1;
        if(x <= mid) change(ls,l,mid,x,d);
        else change(rs,mid + 1,r,x,d);
        tr[i] = up(tr[i],tr[ls],tr[rs]);
    }
    node query(int i,int l,int r,int ql,int qr)
    {
        if(l == ql && r == qr) return tr[i];
        int mid = l + r >> 1;
        if(qr <= mid) return query(ls,l,mid,ql,qr);
        else if(ql > mid) return query(rs,mid + 1,r,ql,qr);
        else
        {
            node tr1 = query(ls,l,mid,ql,mid),tr2 = query(rs,mid + 1,r,mid + 1,qr);
            node res = up(res,tr1,tr2);
            return res;
        }
    }
}T;
int main()
{
    freopen("seq.in","r",stdin);
    freopen("seq.out","w",stdout);
    n = read(),m = read();
    for(int i = 1;i <= n;i++) a[i] = read(),num[a[i]]++;
    for(int i = 1;i <= n;i++) 
    {
        sum[i] = sum[i - 1] + num[i];
        if(sum[i] != i && num[i]) ok[i] = 1;
    }
    //for(int i = 1;i <= n;i++) printf("%d ",ok[i]);
    //cout << endl;
    T.build(1,1,n);
    while(m--)
    {
        int op = read();
        if(op == 1)
        {
            int x = read();
            node ans = T.query(1,1,n,1,x);
            if(!ans.sum) { printf("0\n"); }
            else printf("%d\n",sum[ans.rm]);
        }
        else
        {
            int x = read(),y = read();
            int p = a[x];
            a[x] += y;
            if(y == -1)
            {
                sum[p - 1]++;
                if(sum[p] - sum[p - 1] == 0) T.change(1,1,n,p,0);
                if(sum[p - 1] == p - 1) T.change(1,1,n,p - 1,0);
                else T.change(1,1,n,p - 1,1);
            }
            else
            {
                sum[p]--;
                if(sum[p] - sum[p - 1] == 0) T.change(1,1,n,p,0);
                else 
                {
                    if(sum[p] == p) T.change(1,1,n,p,0);
                    else T.change(1,1,n,p,1);
                }
                if(sum[p + 1] == p + 1) T.change(1,1,n,p + 1,0);
                else T.change(1,1,n,p + 1,1);
            }    
        }
    }
}
/*
6 7
2 3 4 6 6 6
1 6
2 4 -1
2 4 -1
1 6
1 4
2 2 -1
1 6
*/
     
View Code

 

T3:https://www.luogu.org/problem/T92606

When the examination questions to the net to do this, the result tree dp badly written, a look at this complexity does not explode? So give up

Initial idea: f [u] [i] [j]: u and u subtree, an i-th distribution, number, j up to cover a number of points 2

      So u first enumeration assignments, then dp subtree v, v and then give distribution pumps do dp, during the temporary array record

      The second question on the half, when assigned to u pump the distribution plan can be legitimate

Thus O (T * n * 200 ^ 3 * logai), GG

And then looked away suddenly realized standard

In dealing with u, we can first deal with v, f array update

After u all sub-trees have been processed, and finally give u distribution pumps

Plus temporary array, is also very good writing

 
     getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        (ans *= 10) += ch - '0';
        ch = getchar();
    }
    return ans * op;
}
const int maxn = 25;
const int M = 55;
struct egde
{
    int to,next;
}e[maxn << 1];
int fir[maxn],alloc;
void adde(int u,int v)
{
    e[++alloc].next = fir[u],fir[u] = alloc,e[alloc].to = v;
    swap(u,v);
    e[++alloc].next = fir[u],fir[u] = alloc,e[alloc].to = v;
}
int n,a[maxn],s1,s2,p1,p2;//p1 > p2
int f[25][M][M],tmp[M][M];
int mid,ans;
void dp(int u,int fa)
{
    for(int i = fir[u];i;i = e[i].next)
    {
        int v = e[i].to;
        if(v == fa) continue;
        dp(v,u);
        clr(tmp);
        for(int i = 0;i <= s1;i++)
            for(int j = 0;j <= s2;j++)
                for(int x = 0;x <= i;x++)
                    for(int y = 0;y <= j;y++)
                        tmp[i][j] = max(tmp[i][j],f[u][i - x][j - y] + f[v][x][y]);
        for(int i = 0;i <= s1;i++)
            for(int j = 0;j <= s2;j++)
                f[u][i][j] = tmp[i][j];
    }
    clr(tmp);
    for(int i = 0;i <= s1;i++)
        for(int j = 0;j <= s2;j++)
            for(int x = 0;x <= i;x++)
                for(int y = 0;y <= j;y++)
                if(x * p1 + y * p2 >= a[u] && x * p1 + y * p2 - a[u] <= mid)
                    tmp[i][j] = max(tmp[i][j],f[u][i - x][j - y] + 1);
    for(int i = 0;i <= s1;i++)
        for(int j = 0;j <= s2;j++)
            f[u][i][j] = tmp[i][j];
}
bool solve()
{
    clr(f);
    dp(1,0);
    int res = 0;
    for(int i = 0;i <= s1;i++)
        for(int j = 0;j <= s2;j++)
            res = max(res,f[1][i][j]);
    return res == ans;
}
main()
{
    freopen("system.in","r",stdin);
    freopen("system.out","w",stdout);
    int t = read();
    while(t--)
    {
        int n = read(); clr(fir); alloc = 0;
        for(int i = 1;i <= n;i++) a[i] = read();
        for(int i = 1;i < n;i++)
        {
            int u = read(),v = read();
            adde(u,v);
        }
        s1 = read(),s2 = read(),p1 = read(),p2 = read();
        mid = 1000000000;
        clr(f);
        dp(1,0);
        ans = 0;
        for(int i = 0;i <= s1;i++)
            for(int j = 0;j <= s2;j++)
                ans = max(ans,f[1][i][j]);        
        printf("%lld ",ans);
        int l = 0,r = 1000000000,prel = 0,prer = 0;
        int res = 0;
        while(l < r)
        {
            mid = (l + r) >> 1ll;
            if(solve()) r = mid,res = mid;
            else l = mid + 1;
            if(l == prel && r == prer) res = r,r--;
            prel = l,prer = r;
        }
        printf("%lld\n",res);
    }
}
/*
1
4
5 30 20 20
1 2
1 3
3 4
4 1 10 15
*/
            
View Code

 

Guess you like

Origin www.cnblogs.com/LM-LBG/p/11329376.html