半期考试(几近爆零场)

T3 大冒险

 

 

可以观察找规律!

最终把所有矩阵都给放在d*d的矩阵内,然后就变成了哪一个点没有被矩阵覆盖。

扫描线差不多的方法即可!

离线x维,然后y维用线段树区间修改。

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define py pair<int,int>
const int N=2e5+6;
struct node{int h, x, y, d;}A[N<<2];
inline bool cmp(const node&x, const node&y){return x.h<y.h;}
int cnt, n, d;
void add(int x, int y, int xx, int yy)
{
    A[++cnt]=(node){x, y, yy, 1};
    A[++cnt]=(node){xx+1, y, yy, -1};
}
py tr[N<<2];int lzy[N<<2];
void build(int p,int l,int r)
{
    tr[p]=py(0,l);
    lzy[p]=0;
    if(l==r)return;
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    tr[p]=min(tr[p<<1],tr[p<<1|1]);
}
inline void modi(int p,int d)
{
    tr[p].first+=d;
    lzy[p]+=d;
}
inline void putdown(int p)
{
    modi(p<<1,lzy[p]);
    modi(p<<1|1,lzy[p]);
    lzy[p]=0;
}
void ins(int p,int l,int r,int x,int y,int d)
{
    if(x<=l&&r<=y){modi(p,d);return;}
    if(lzy[p])putdown(p);
    int mid=(l+r)>>1;
    if(x<=mid)ins(p<<1,l,mid,x,y,d);
    if(y>mid)ins(p<<1|1,mid+1,r,x,y,d);
    tr[p]=min(tr[p<<1],tr[p<<1|1]);
}
void work()
{
    cnt=0;
    scanf("%d%d",&n,&d);
    int flag=0, x, y, xx, yy, f1, f2, t1, t2;
    while(n--)
    {
        scanf("%d%d%d%d",&x,&y,&xx,&yy);
        xx--;yy--;
        f1=x%d, f2=xx%d, t1=y%d, t2=yy%d;
        (f1+=d)%=d;(f2+=d)%=d;(t1+=d)%=d;(t2+=d)%=d;
        if(xx-x+1>=d&&yy-y+1>=d)flag=1;
        if(flag)continue;
        if(xx-x+1>=d)
        {
            if(t1<=t2) add(0, t1, d-1, t2);
            else add(0, 0, d-1, t2),add(0, t1, d-1, d-1);
        }
        else
        {
            if(f1<=f2)
            {
                if(yy-y+1>=d) add(f1, 0, f2, d-1);
                else
                {
                    if(t1<=t2) add(f1, t1, f2, t2);
                    else add(f1, 0, f2, t2),add(f1, t1, f2, d-1);
                }
            }
            else
            {
                if(yy-y+1>=d)
                {
                    add(0, 0, f2, d-1);
                    add(f1, 0, d-1, d-1);
                }
                else
                {
                    if(t1<=t2)
                    {
                        add(0, t1, f2, t2);
                        add(f1, t1, d-1, t2);
                    }
                    else
                    {
                        add(0, 0, f2, t2);
                        add(0, t1, f2, d-1);
                        add(f1, 0, d-1, t2);
                        add(f1, t1, d-1, d-1);
                    }
                }
            }
        }
    }
    if(flag){puts("NO");return;}
    sort(A+1,A+1+cnt,cmp);
    int nw=1;
    d--;build(1,0,d);
    for(re i=0;i<=d;++i)
    {
        while(nw<=cnt && A[nw].h<=i)
        {
            ins(1,0,d,A[nw].x,A[nw].y,A[nw].d);
            nw++;
        }
        py pos=tr[1];
        if(pos.first==0)
        {
            puts("YES");
            printf("%d %d\n", i, pos.second);
            return;
        }
    }
    puts("NO");
}
signed main()
{
    int T;
    scanf("%d",&T);
    while(T--)work();
    return 0;
}

 

T4 单调栈

 

 如果没有-1,那么应该很容易想到笛卡尔树求答案,很简单。

但是有-1的话,他会导致笛卡尔树形态不一定,所以可以区间dp

#include<stdio.h>
const int mo=1e9+7;
int f[105][105][105], C[105][105], a[105];
signed main(){
    C[0][0]=1;
    for(int i=1;i<=99;++i){
        C[i][0]=1;
        for(int j=1;j<=99;++j) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mo;
    }int T,n,l,r;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%d",&a[i]);
        for(int i=1;i<=n;++i)for(int j=i;j<=n;++j)for(int d=1;d<=n;++d) f[i][j][d]=0;
        for(int i=n;i;--i)
        for(int j=i;j<=n;++j) for(int k=i;k<=j;++k){
            if(a[k]==-1)l=1,r=i; else l=r=a[k];
            for(int d=l;d<=r;++d){
                f[i][j][d]+=1LL*(i<k?f[i][k-1][d]:1)*(k<j?f[k+1][j][d+1]:1)%mo*C[j-i][k-i]%mo;
                if(f[i][j][d]>=mo)f[i][j][d]-=mo;
            }
        }printf("%d\n",f[1][n][1]);
    }return 0;
}

 

posted @ 2021-11-15 21:52  kzsn  阅读(49)  评论(0编辑  收藏  举报