2019-8-5 test summary

A. Matrix Games

Water is a problem, but still wanted to for a long time.

The contribution of each point of the answer is $ A [i] [j] \ times H [i] \ times Z [j] $,

This is then $ SUM $ $ \ sum A [i] [j] \ times H [i] \ times Z [j] $,

The $ H [i] $ proposed, i.e. $ \ sum (H [i] \ times \ sum A [i] [j] \ times Z [j]) $,

The $ A [i] [j] $ is regular,

This line is the difference between the previous line and $ m \ times \ sum Z [j] $,

Then you can transfer the line by line.

Finally, $ O (n) $ of.

Ugly code:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#define Maxn 1000050
#define Reg register
#define INF 0x7ffffff
#define int long long
#define mod 1000000007
using namespace std;
int n,m,k,sum=0,ans=0,H[Maxn],Z[Maxn],dp[Maxn];
string s;
signed main()
{
    scanf("%lld%lld%lld",&n,&m,&k);
    for(Reg int i=1;i<=n;++i) H[i]=Z[i]=1;
    for(Reg int i=1;i<=m;++i) H[i]=Z[i]=1;
    for(Reg int i=1,x,y;i<=k;++i)
    {
        cin>>s;
        scanf("%lld%lld",&x,&y);
        if(s[0]=='R') H[x]=(H[x]*y)%mod;
        else Z[x]=(Z[x]*y)%mod;
    }
    for(Reg int i=1;i<=m;++i)
    {
        dp[1]=(dp[1]+i*Z[i]%mod)%mod;
        sum=(sum+Z[i])%mod;
    }
    for(Reg int i=2;i<=n;++i)
        dp[i]=(dp[i-1]+m*sum%mod)%mod;
    for(Reg int i=1;i<=n;++i)
        ans=(ans+H[i]*dp[i]%mod)%mod;
    printf("%lld",ans);
    return 0;
}
View Code

 

B. Hopscotch

 

C. graceful sequence

Mo began to think of a team ( why they are asked to think of divide and conquer ),

I thought I could expand to the left, so I want the team on towards Mo.

Finally found, in fact, Mo team not as good as direct violence.

$ 2 $ open segment tree pieces, a number of the most value in the interval, a value of the position is the period number.

Each inquiry directly to the farthest of the two values, left or right to expand.

Finally, get $ 80 $ points $ TLE $.

Ugly code:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#define int long long
#define Maxn 100050
#define Reg register
#define INF 0x7ffffff
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;
int n,m,ansm,ansn,maxx,minn,A[Maxn],pos[Maxn];
struct Tree {Tree *lch,*rch; int mx,mn;};
Tree *New()
{
    Tree *p=new Tree;
    p->lch=p->rch=NULL;
    p->mx=-INF,p->mn=INF;
    return p;
}
Tree *rot1=New(),*rot2=New();
void up(Tree *p)
{
    p->mx=-INF,p->mn=INF;
    if(p->lch!=NULL)
    {
        p->mx=max(p->lch->mx,p->mx);
        p->mn=min(p->lch->mn,p->mn);
    }
    if(p->rch!=NULL)
    {
        p->mx=max(p->rch->mx,p->mx);
        p->mn=min(p->rch->mn,p->mn);
    }
    return;
}
void build(Tree **p,int l,int r)
{
    if(*p==NULL) *p=New();
    if(l==r)
    {
        (*p)->mx=(*p)->mn=pos[l];
        return;
    }
    int mid=(l+r)>>1;
    if(l<=mid) build(&((*p)->lch),l,mid);
    if(mid+1<=r) build(&((*p)->rch),mid+1,r);
    up(*p);
    return;
}
void bup(Tree **p,int l,int r)
{
    if(*p==NULL) *p=New();
    if(l==r)
    {
        (*p)->mx=(*p)->mn=A[l];
        return;
    }
    int mid=(l+r)>>1;
    if(l<=mid) bup(&((*p)->lch),l,mid);
    if(mid+1<=r) bup(&((*p)->rch),mid+1,r);
    up(*p);
    return;
}
void ask(Tree *p,int l,int r,int sol,int sor)
{
    if(p==NULL||(p->mx<=ansm&&p->mn>=ansn)) return;
    if(sol<=l&&r<=sor)
    {
        ansm=max(ansm,p->mx);
        ansn=min(ansn,p->mn);
        return;
    }
    int mid=(l+r)>>1;
    if(sol<=mid) ask(p->lch,l,mid,sol,sor);
    if(mid+1<=sor) ask(p->rch,mid+1,r,sol,sor);
    return;
}
void query(Tree *p,int l,int r,int sol,int sor)
{
    if(p==NULL||(p->mx<=maxx&&p->mn>=minn)) return;
    if(sol<=l&&r<=sor)
    {
        maxx=max(maxx,p->mx);
        minn=min(minn,p->mn);
        return;
    }
    int mid=(l+r)>>1;
    if(sol<=mid) query(p->lch,l,mid,sol,sor);
    if(mid+1<=sor) query(p->rch,mid+1,r,sol,sor);
    return;
}
signed main()
{
//    freopen("text.in","r",stdin);
    scanf("%lld",&n);
    for(Reg int i=1;i<=n;++i)
    {
        scanf("%lld",&A[i]);
        pos[A[i]]=i;
    }
    build(&rot1,1,n); bup(&rot2,1,n);
    scanf("%lld",&m);
    for(Reg int i=1,l,r;i<=m;++i)
    {
        maxx=-INF,minn=INF;
        scanf("%lld%lld",&l,&r);
        query(rot2,1,n,l,r);
        int ln=l,rn=r;
        while(1)
        {
            if(maxx-minn==rn-ln||(ln==1&&rn==n))
            {
                printf("%lld %lld\n",ln,rn);
                break;
            }
            ansm=-INF,ansn=INF;
            ask(rot1,1,n,minn,maxx);
            ln=ansn,rn=ansm;
            query(rot2,1,n,ln,rn);
        }
    }
    return 0;
}
View Code

 

to sum up:

$ T1 $ no idea at first glance,

The beginning has been thinking about how to use the tree line.

Anyway are $ complexity O (nm) $ a.

Then discard the.

Finally, the code finished $ T3 $ have come back to see $ T1 $, thought for a moment.

Write down the formula, I discovered that in fact it is water. Progressive transfer it.

I began to see $ T2 $, have no idea.

A code of violence ( finally wrong ), first got to say this violence points.

$ T3 $ seems to have done the way, the team thought that Mo topic in the $ permu $, frame of mind will explode.

Because I did not do that problem.

Want to stop and take, the result code $ 2 $ teeth segment tree, then water to $ 80 $ points.

Finally, go back to see $ T1 $ and $ T2 $, $ T1 $ kick really mind it steady.

Then $ T2 $ or explode, violence did not get points.

So finally $ 100 + $ 185 = 80 + 5.

Nothing levels. . .

Guess you like

Origin www.cnblogs.com/Milk-Feng/p/11302189.html