EZ 2018 05 04 NOIP2018 Mock Competition (12)

This test paper should motivate us.

Then everyone's score was very high, and then I was stoked by a group of 240 gangsters of Second A T2 with 210.

Lost 5 rating but Rank actually killed X_o_r dalao && YZC dalao

On the Importance of Writing About Violence

T1

Sincere water, you can directly DFS burst search

O(2^n) will not exceed, after n is large, you can DP, the sign-in question is not explained

CODE

#include<cstdio>
using namespace std;
typedef long long LL;
const int N=20;
int n,a[N],b[N],c[N],d[N];
LL ans=0;
inline LL max(LL a,LL b)
{
    return a>b?a:b;
}
inline void DFS(int now,int tot1,int tot2)
{
    if (now>n) { ans=max(ans,(LL)tot1*tot2); return; }
    DFS(now+1,tot1+a[now],max(tot2-b[now],0));
    DFS(now+1,max(tot1-d[now],0),tot2+c[now]);
}
int main()
{
    //freopen("A.in","r",stdin); freopen("A.out","w",stdout);
    register int i;
    for (scanf("%d",&n),i=1;i<=n;++i)
    scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    DFS(1,0,0);
    printf("%lld",ans);
    return 0;
}

T2

I go to the conclusion of this question

I remember that LowestJN dalao told a very important formula for T2 in this test paper .

In an acyclic graph, the number of connected blocks = the number of points - the number of edges

Is this an SB question?

We two-dimensional prefix and count the number of points and edges, just allow it

The algorithm for points is relatively simple. For edges, the number of edges in the row should be counted. . .

See the CODE for yourself

CODE

#include<cstdio>
using namespace std;
const int N=2005;
bool a[N][N];
int h[N][N],l[N][N],node[N][N],edge[N][N],n,m,q,x1,x2,y1,y2;
inline char tc(void)
{
    static char fl[100000],*A=fl,*B=fl;
    return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
    x=0; char ch=tc();
    while (ch<'0'||ch>'9') ch=tc();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(int x)
{
    if (x/10) write(x/10);
    putchar(x%10+'0');
}
inline void init(void)
{
    register int i,j;
    for (i=1;i<=n;++i)
    for (j=1;j<=m;++j)
    {
        node[i][j]=node[i-1][j]+node[i][j-1]-node[i-1][j-1]+a[i][j];
        edge[i][j]=edge[i-1][j]+edge[i][j-1]-edge[i-1][j-1]+(a[i][j]&&a[i-1][j])+(a[i][j]&&a[i][j-1]);
        h[i][j]=h[i][j-1]+(a[i][j]&&a[i][j-1]); l[i][j]=l[i-1][j]+(a[i][j]&&a[i-1][j]);
    }
}
int main()
{
    //freopen("B.in","r",stdin); freopen("B.out","w",stdout);
    register int i,j;
    read(n); read(m); read(q);
    for (i=1;i<=n;++i)
    for (j=1;j<=m;++j)
    {
        char ch=tc();
        while (ch!='0'&&ch!='1') ch=tc();
        a[i][j]=ch-'0';
    }
    init();
    while (q--)
    {
        read(x1); read(y1); read(x2); read(y2);
        int d=node[x2][y2]-node[x1-1][y2]-node[x2][y1-1]+node[x1-1][y1-1];
        int b=edge[x2][y2]-edge[x1][y2]-edge[x2][y1]+edge[x1][y1]+h[x1][y2]-h[x1][y1]+l[x2][y1]-l[x1][y1];
        write(d-b); putchar('\n');
    }
    return 0;
}

T3

Differentiated mathematics + data structure magic question, anyway, I guessed a conclusion

First, if the line segments do not intersect then there is no ghost value

Obviously, because the y coordinate keeps rising, so usemath postureCommon sense knows that only when the x coordinate goes to the front can the line segment intersect

So if only two line segments intersect (no three or more line segments intersect at the same point)

Then the problem is transformed into: find the inverse logarithm of x[1],x[2],...,x[n]

But what if three or more line segments intersect at the same point?

Bold guess conclusion - no such situation

But that's it, I jumped to this conclusion when I took the test and found it right after taking the big sample.

Then don't care about the direct 40 separation + tree array

In fact, the standard calculation also uses the properties of the arithmetic sequence , just do it.

Because we found that the x array is composed of no more than a segment of arithmetic progression

If x[i]>a, let the inverse pair generated by x[i] be y, and there are z segments of arithmetic progression in front

Then the inverse logarithm generated by x[i] is yz

The reason is: in each arithmetic sequence, there must be a number that can form an inverse pair with x[i-1], but cannot form an inverse pair with x[i]. Then the contribution of each arithmetic sequence will be reduced by 1.

Then O(1) transfer can be done

If x[i]<a, then the direct tree-like array counts all the transitions of x[i]<a before it

I'm still afraid that I can't explain clearly, here are the details sol

By the way, %%% CJJ dalao is the leader of the pack

Streamlined CODE

#include<cstdio>
using namespace std;
typedef long long LL;
const int MAXA=1e5+10;
int tree[MAXA],n,a,now,x,cnt,last,mod;
LL ans;
inline void inc(int &x,int y)
{
    if ((x+=y)>=mod) x-=mod,++cnt;
}
inline int lowbit(int x)
{
    return x&(-x);
}
inline void add(int x)
{
    while (x<=a) ++tree[x],x+=lowbit(x);
}
inline int get(int x)
{
    int tot=0;
    while (x) tot+=tree[x],x-=lowbit(x);
    return tot;
}
int main()
{
    //freopen("C.in","r",stdin); freopen("C.out","w",stdout);
    scanf("%d%d%d%d",&n,&x,&a,&mod); now=x;
    register int i;
    for (i=1;i<=n;++i)
    {
        if (now>=a) { last-=cnt; if (now<x) ++last; } else last=i-get(now)-1,add(now+1);
        ans+=last; inc(now,a);
    }
    printf("%lld",ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325682707&siteId=291194637