高一上十二月上、中旬日记

12.1

闲话

做题纪要

12.2

闲话

做题纪要

12.3

闲话

  • 在机房补 whk

做题纪要

luogu P9759 [COCI2022-2023#3] Bomboni

  • 将原状态设计中 modk 一维改为与 kgcd 即可。

    点击查看代码
    const int p=998244353;
    int a[510][510],f[510][510][310],d[1000010],g[310],gd[510][510];
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int n,m,cnt=0,i,j,k;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]!=-1)
                {
                    a[i][j]=__gcd(a[i][j],m);
                }
            }
        }
        for(i=1;i<=m;i++)
        {
            if(m%i==0)
            {
                cnt++;
                d[i]=cnt;
                g[cnt]=i;
            }
        }
        for(i=1;i<=cnt;i++)
        {
            for(j=1;j<=cnt;j++)
            {
                gd[i][j]=d[__gcd(1ll*m,1ll*g[i]*g[j])];
            }
        }
        f[1][1][d[a[1][1]]]=1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(a[i][j]!=-1)
                {
                    for(k=1;k<=cnt;k++)
                    {
                        if(i+1<=n&&a[i+1][j]!=-1)
                        {
                            f[i+1][j][gd[k][d[a[i+1][j]]]]=(f[i+1][j][gd[k][d[a[i+1][j]]]]+f[i][j][k])%p;
                        }
                        if(j+1<=n&&a[i][j+1]!=-1)
                        {
                            f[i][j+1][gd[k][d[a[i][j+1]]]]=(f[i][j+1][gd[k][d[a[i][j+1]]]]+f[i][j][k])%p;
                        }
                    }
                }
            }
        }
        printf("%d\n",f[n][n][cnt]);
        return 0;
    }
    
    

12.4

闲话

  • 在机房补 whk

做题纪要

12.5

闲话

做题纪要

12.6

闲话

做题纪要

12.7

闲话

  • 在机房补 whk

做题纪要

12.8

闲话

  • 在机房补 whk

做题纪要

12.9

闲话

  • 在机房补 whk

做题纪要

luogu P11361 [NOIP2024] 编辑字符串

  • 直接将能相互交换的缩成一段然后开两个指针分别去扫,因需要处理两段的交需要较多的分讨。

  • 贪心策略显然是能成功匹配的地方一定进行匹配,不妨枚举最优情况下答案的形态。

  • 具体地,仍处理出每个字符所属于的极长连续段内 0/1 的个数。只用一个指针向右扫,若存在能成功匹配的就进行匹配,否则不让其成功匹配。正确性的话,可以考虑若本次未成功匹配但存在互换颜色后上次也没有进行成功匹配则一定不合法。

    点击查看代码
    int pos[3][100010],sum[3][100010][2];
    char s[3][100010],t[3][100010];
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("edit.in","r",stdin);
        freopen("edit.out","w",stdout);
    #endif
        int testcase,n,ans=0,flag,i,j,k;
        scanf("%d",&testcase);
        for(k=1;k<=testcase;k++)
        {
            ans=0;
            scanf("%d%s%s%s%s",&n,s[1]+1,s[2]+1,t[1]+1,t[2]+1);
            memset(sum,0,sizeof(sum));
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=2;j++)
                {
                    pos[j][i]=(t[j][i]=='1'&&t[j][i-1]=='1')?pos[j][i-1]:i;
                    sum[j][pos[j][i]][0]+=(s[j][i]=='0');
                    sum[j][pos[j][i]][1]+=(s[j][i]=='1');	
                }
            }
            for(i=1;i<=n;i++)
            {
                for(flag=j=0;j<=1&&flag==0;j++)
                {
                    if(sum[1][pos[1][i]][j]>=1&&sum[2][pos[2][i]][j]>=1)
                    {
                        ans++;
                        flag=1;
                        sum[1][pos[1][i]][j]--;
                        sum[2][pos[2][i]][j]--;
                    }
                }
                for(j=0;j<=1&&flag==0;j++)
                {
                    if(sum[1][pos[1][i]][j]>=1&&sum[2][pos[2][i]][1^j]>=1)
                    {
                        flag=1;
                        sum[1][pos[1][i]][j]--;
                        sum[2][pos[2][i]][1^j]--;
                    }
                }
            }
            printf("%d\n",ans);
        }
        return 0;
    }
    

559. 选择

  • 观察到至多跳 O(log) 遍,接着暴力即可。

    点击查看代码
    ll a[1000010];
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll n,m,ans=0,sum=0,x,i,j,k;
        scanf("%lld",&n);
        m=log2(n)+1;
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        for(i=0;i<=(1<<m)-1;i++)
        {
            x=1;
            sum=a[1];
            for(j=0;j<=m;j++)
            {
                if((i>>j)&1)
                {
                    x+=(1<<j);
                    if(x>n)
                    {
                        break;
                    }
                    sum+=a[x];
                }
            }
            ans=max(ans,sum);
        }
        printf("%lld\n",ans);
        return 0;
    }
    

560. 填空

  • 找到最大子矩形后判断即可。

    点击查看代码
    ll h[1000010],l[1000010];
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll t,n,m,p,q,w,a,b,i,j;
        scanf("%lld",&t);
        for(j=1;j<=t;j++)
        {
            a=b=0;
            scanf("%lld%lld%lld%lld%lld",&n,&m,&p,&q,&w);
            for(i=1;i<=p;i++)
            {
                scanf("%lld",&h[i]);
                a=max(a,h[i]-h[i-1]-1);
            }
            a=max(a,n-h[p]);
            for(i=1;i<=q;i++)
            {
                scanf("%lld",&l[i]);
                b=max(b,l[i]-l[i-1]-1);
            }
            b=max(b,m-l[q]);
            if(a*b>=w)
            {
                printf("Y\n");
            }
            else
            {
                printf("N\n");
            }
        }
        return 0;
    }
    

561. 计算

  • 二维前缀和后二分答案。

    点击查看代码
    int sum[510][510],x[510],y[510];
    int query(int x1,int y1,int x2,int y2)
    {
        return sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
    }
    bool check(int mid,int n,int m)
    {
        int maxx=0;
        for(int i=1;i<=m;i++)
        {
            maxx=max(maxx,query(max(x[i]-mid,1),max(y[i]-mid,1),min(x[i]+mid,n),min(y[i]+mid,n)));
        }
        return 2*maxx>=m;
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int n,m,l=0,r,ans=0,mid,i,j;
        cin>>n>>m;
        for(i=1;i<=m;i++)
        {
            cin>>x[i]>>y[i];
            sum[x[i]][y[i]]++;
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
            }
        }
        r=n/2;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(check(mid,n,m)==true)
            {
                r=mid-1;
                ans=2*mid+1;
            }
            else
            {
                l=mid+1;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    

12.10

闲话

  • 在机房补 whk

做题纪要

12.11

闲话

  • 在机房补 whk

做题纪要

525. 雷

  • z 为边权求单源最短路得到比率后高精模拟加法。

    点击查看代码
    struct node
    {
        ll nxt,to,w;
    }e[400010];
    ll head[400010],dis[400010],vis[400010],a[400010],ans[400010],cnt=0;
    void add(ll u,ll v,ll w)
    {
        cnt++;
        e[cnt].nxt=head[u];
        e[cnt].to=v;
        e[cnt].w=w;
        head[u]=cnt;
    }
    void spfa(ll s)
    {
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<ll>q;
        q.push(s);
        dis[s]=0;
        vis[s]=1;
        while(q.empty()==0)
        {
            ll x=q.front();
            vis[x]=0;
            q.pop();
            for(ll i=head[x];i!=0;i=e[i].nxt)
            {
                if(dis[e[i].to]>dis[x]+e[i].w)
                {
                    dis[e[i].to]=dis[x]+e[i].w;
                    if(vis[e[i].to]==0)
                    {
                        q.push(e[i].to);
                        vis[e[i].to]=1;
                    }
                }
            }
        }
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll n,m,u,v,w,i;
        cin>>n>>m;
        for(i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        for(i=1;i<=m;i++)
        {
            cin>>u>>v>>w;
            add(u,v,-w);
        }
        spfa(1);
        for(i=1;i<=n;i++)
        {
            if(dis[i]+30>=0)
            {
                ans[dis[i]+30]+=a[i];
            }
        }
        ans[0]=20000;
        for(i=1;i<=20000;i++)
        {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
        if(ans[23]>=5)
        {
            ans[24]++;
            for(i=24;i<=20000;i++)
            {
                ans[i+1]+=ans[i]/10;
                ans[i]%=10;
            }	
        }
        while(ans[0]>=31&&ans[ans[0]]==0)
        {
            ans[0]--;
        }
        for(i=ans[0];i>=30;i--)
        {
            cout<<ans[i];
        }
        cout<<".";
        for(i=29;i>=24;i--)
        {
            cout<<ans[i];
        }
        return 0;
    }
    

12.12

闲话

  • 在机房补 whk

做题纪要

51Nod 1202.子序列个数

  • fi 表示 [1,i] 中本质不同子序列的个数,状态转移方程为 fi={2fi1flastai1lastai02fi1+1lastai=0

  • 视题目要求决定是否要加上空串的贡献。

    点击查看代码
    const ll p=1000000007;
    ll f[1000010],last[1000010],a[1000010];
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll n,i;	
        cin>>n;
        for(i=1;i<=n;i++)
        {
            cin>>a[i];
            if(last[a[i]]!=0)
            {
                f[i]=(2*f[i-1]-f[last[a[i]]-1]%p+p)%p;
            }
            else
            {
                f[i]=(2*f[i-1]+1)%p;
            }
            last[a[i]]=i;
        }
        cout<<(f[n]+1)%p<<endl;
        return 0;
    }
    

HZOJ 369. 稳稳的拼三角形

  • 排序后肯定是连续三个一起选。考虑一次匹配失败后最小的数的值域至少除以 2 ,故只保留前 log 大进行判断。计算保留个数时应参考斐波那契的构造方式使得区间长度 45 个数时一定有解。

  • 线段树上归并排序维护即可。

    点击查看代码
    int a[100010];
    struct SMT
    {
        struct SegmentTree
        {
            vector<int>val;
            SegmentTree operator + (const SegmentTree &another)
            {
                SegmentTree tmp;
                int x=0,y=0;
                while(x<val.size()&&y<another.val.size())
                {
                    if(val[x]>another.val[y])
                    {
                        tmp.val.push_back(val[x]);
                        x++;
                    }
                    else
                    {
                        tmp.val.push_back(another.val[y]);
                        y++;
                    }
                }
                while(x<val.size())
                {
                    tmp.val.push_back(val[x]);
                    x++;
                }
                while(y<another.val.size())
                {
                    tmp.val.push_back(another.val[y]);
                    y++;
                }
                while(tmp.val.size()>=45)
                {
                    tmp.val.pop_back();
                }
                return tmp;
            }
        }tree[400010],ans;
        #define lson(rt) (rt<<1)
        #define rson(rt) (rt<<1|1)
        void pushup(int rt)
        {
            tree[rt]=tree[lson(rt)]+tree[rson(rt)];
        }
        void build(int rt,int l,int r)
        {
            if(l==r)
            {
                tree[rt].val.push_back(a[l]);
                return;
            }
            int mid=(l+r)/2;
            build(lson(rt),l,mid);
            build(rson(rt),mid+1,r);
            pushup(rt);
        }
        void update(int rt,int l,int r,int pos,int val)
        {
            if(l==r)
            {
                tree[rt].val[0]=val;
                return;
            }
            int mid=(l+r)/2;
            if(pos<=mid)
            {
                update(lson(rt),l,mid,pos,val);
            }
            else
            {
                update(rson(rt),mid+1,r,pos,val);
            }
            pushup(rt);
        }
        void query(int rt,int l,int r,int x,int y)
        {
            if(x<=l&&r<=y)
            {
                ans=ans+tree[rt];
                return;
            }
            int mid=(l+r)/2;
            if(x<=mid)
            {
                query(lson(rt),l,mid,x,y);
            }
            if(y>mid)
            {
                query(rson(rt),mid+1,r,x,y);
            }
        }
        int ask(int l,int r,int n)
        {
            ans.val.clear();
            query(1,1,n,l,r);
            for(int i=0;i+2<ans.val.size();i++)
            {
                if(ans.val[i]<ans.val[i+1]+ans.val[i+2])
                {
                    return ans.val[i]+ans.val[i+1]+ans.val[i+2];
                }
            }
            return 0;
        }
    }T;
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int n,q,pd,l,r,i;
        cin>>n>>q;
        for(i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        T.build(1,1,n);
        for(i=1;i<=q;i++)
        {
            cin>>pd>>l>>r;
            if(pd==1)
            {
                T.update(1,1,n,l,r);
            }
            else
            {
                cout<<T.ask(l,r,n)<<endl;
            }
        }
        return 0;
    }
    

12.13

闲话

  • 在机房补 whk

做题纪要

12.14

闲话

  • 在机房补 whk

做题纪要

luogu P10552 [THUPC 2024 决赛] 警钟长鸣

  • 输出下发文件。

    点击查看代码
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        cout<<"Please carefully check the download files before the contest begins!!!"<<endl;
        return 0;
    }
    

12.15

闲话

做题纪要

luogu P11532 [THUPC2025 初赛] 好成绩

  • 循环。

    点击查看代码
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif	
        int n,i;
        for(int i=0;i<=150;i++)
        {
            if(i%3==2&&i%5==3&&i%7==6)
            {
                cout<<i<<endl;
            }
        }
        return 0;
    }
    

luogu P11529 [THUPC2025 初赛] 辞甲猾扎

  • 限制条件为灰点不能只与白点相邻,即与黑点相邻的点至少要与一个白点相邻。

  • 抽象成 luogu P3942 将军令 后发现只有关键点才需要被计入答案,因为不会写 luogu P2899 [USACO08JAN] Cell Phone Network G 树形 DP 的处理,遂写的是 luogu P3523 [POI2011] DYN-Dynamite 的写法。

    点击查看代码
    struct node
    {
        int nxt,to;
    }e[2000010];
    int head[2000010],black[2000010],vis[2000010],ins[2000010],f[2000010],g[2000010],cnt=0,ans=0;
    vector<int>pos;
    void add(int u,int v)
    {
        cnt++;
        e[cnt].nxt=head[u];
        e[cnt].to=v;
        head[u]=cnt;
    }
    void dfs(int x)
    {
        ins[x]=1;
        f[x]=-0x3f3f3f3f;
        g[x]=0x3f3f3f3f;
        for(int i=head[x];i!=0;i=e[i].nxt)
        {
            if(vis[e[i].to]!=-1&&ins[e[i].to]==0)
            {
                dfs(e[i].to);
                f[x]=max(f[x],f[e[i].to]+1);
                g[x]=min(g[x],g[e[i].to]+1);
            }
        }
        if(g[x]>1&&vis[x]==1)
        {
            f[x]=max(f[x],0);
        }
        if(f[x]+g[x]<=1)
        {
            f[x]=-0x3f3f3f3f;
        }
        if(f[x]==1)
        {
            f[x]=-0x3f3f3f3f;
            g[x]=0;
            ans++;
        }
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int n,k,u,v,i,j;
        scanf("%d%d",&n,&k);
        for(i=1;i<=k;i++)
        {
            scanf("%d",&black[i]);
            vis[black[i]]=-1;
        }
        for(i=1;i<=n-1;i++)
        {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        for(i=1;i<=k;i++)
        {
            for(j=head[black[i]];j!=0;j=e[j].nxt)
            {
                if(vis[e[j].to]!=-1)
                {
                    vis[e[j].to]=1;
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(vis[i]!=-1&&ins[i]==0)
            {
                dfs(i);
                ans+=(f[i]>=0);
            }
        }
        printf("%d\n",ans);
        return 0;
    }
    

luogu B4060 位运算 1

  • 基础位运算。

    点击查看代码
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll a,b,k;
        cin>>a>>b>>k;
        cout<<(a&b)<<endl;
        cout<<(a|b)<<endl;
        cout<<(a^b)<<endl;
        cout<<(~a)<<endl;
        cout<<(a<<k)<<endl;
        cout<<(a>>k)<<endl;
        return 0;
    }
    

luogu B4061 位运算 2

  • 基础位运算。

    点击查看代码
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll a,b;
        cin>>a>>b;
        cout<<(a<<b)<<endl;
        cout<<(a>>b)<<endl;
        cout<<((a>>b)&1)<<endl;
        cout<<(a^(((a>>b)&1)<<b))<<endl;	
        cout<<(a|(1<<b))<<endl;
        cout<<(a^(1<<b))<<endl;
        return 0;
    }
    

luogu P11362 [NOIP2024] 遗失的赋值

  • 先判掉无解的情况,然后将 {c} 排序并去重。考虑将答案分成若干段分别统计方案数然后再乘起来。

  • 对于 [ci,ci+1) 间的答案,考虑正难则反,用总方案数 v2(ci+1ci) 减去不合法的方案数。

  • 由题目限制,不合法方案数只可能来自二元限制与一元限制的冲突,即 aci=dci,aci+1=bci,aci+2=bci+1,,aci+11=bci+12,bci+11dci+1 。其中 aci,bci+11 的取值受到一定限制,故不合法方案数为 (v1)v2(ci+1ci1)

  • 类似地,由于 [1,c1),[cm,n) 不会产生不合法方案,故其贡献分别为 v2(ci1),v2(ncm)

    点击查看代码
    const ll p=1000000007;
    pair<ll,ll>c[100010];
    ll qpow(ll a,ll b,ll p)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)
            {
                ans=ans*a%p;
            }
            b>>=1;
            a=a*a%p;
        }
        return ans;
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("assign.in","r",stdin);
        freopen("assign.out","w",stdout);
    #endif
        ll t,n,m,v,ans=0,i,j;
        scanf("%lld",&t);
        for(j=1;j<=t;j++)
        {
            scanf("%lld%lld%lld",&n,&m,&v);
            for(i=1;i<=m;i++)
            {
                scanf("%lld%lld",&c[i].first,&c[i].second);
            }
            sort(c+1,c+1+m);
            ans=qpow(v,2*(c[1].first-1),p)*qpow(v,2*(n-c[m].first),p)%p;
            for(i=2;i<=m;i++)
            {
                if(c[i].first==c[i-1].first)
                {
                    ans*=(c[i].second==c[i-1].second);
                }
                else
                {
                    ans=ans*(qpow(v,2*(c[i].first-c[i-1].first),p)-(v-1)*qpow(v,c[i].first-c[i-1].first-1,p)%p+p)%p;
                }
            }
            printf("%lld\n",ans);
        }
        return 0;
    }
    

12.16

闲话

  • 在机房补 whk

做题纪要

12.17

闲话

做题纪要

luogu P10799 「CZOI-R1」三角形与树

  • HZOJ 369. 稳稳的拼三角形 一样套个树剖即可。

    点击查看代码
    struct node
    {
        ll nxt,to;
    }e[200010];
    ll head[200010],fa[200010],siz[200010],dep[200010],son[200010],dfn[200010],top[200010],a[100010],n,cnt=0,tot=0;
    vector<ll>tmp;
    void add(ll u,ll v)
    {
        cnt++;
        e[cnt].nxt=head[u];
        e[cnt].to=v;
        head[u]=cnt;
    }
    void dfs1(ll x,ll father)
    {
        siz[x]=1;
        fa[x]=father;
        dep[x]=dep[father]+1;
        for(ll i=head[x];i!=0;i=e[i].nxt)
        {
            if(e[i].to!=father)
            {
                dfs1(e[i].to,x);
                siz[x]+=siz[e[i].to];
                son[x]=(siz[e[i].to]>siz[son[x]])?e[i].to:son[x];
            }
        }
    }
    void dfs2(ll x,ll id)
    {
        top[x]=id;
        tot++;
        dfn[x]=tot;
        if(son[x]!=0)
        {
            dfs2(son[x],id);
            for(ll i=head[x];i!=0;i=e[i].nxt)
            {
                if(e[i].to!=fa[x]&&e[i].to!=son[x])
                {
                    dfs2(e[i].to,e[i].to);
                }
            }
        }
    }
    struct BIT
    {
        ll c[100010];
        ll lowbit(ll x)
        {
            return (x&(-x));
        }
        void add(ll n,ll x,ll val)
        {
            for(ll i=x;i<=n;i+=lowbit(i))
            {
                c[i]^=val;
            }
        }
        void update(ll l,ll r,ll val)
        {
            add(n,l,val);
            add(n,r+1,val);
        }
        ll getsum(ll x)
        {
            ll ans=0;
            for(ll i=x;i>=1;i-=lowbit(i))
            {
                ans^=c[i];
            }
            return ans;
        }
    }T;	
    void update(ll u,ll v,ll w)
    {
        while(top[u]!=top[v])
        {
            if(dep[top[u]]>dep[top[v]])
            {
                T.update(dfn[top[u]],dfn[u],w);
                u=fa[top[u]];
            }
            else
            {
                T.update(dfn[top[v]],dfn[v],w);
                v=fa[top[v]];
            }
        }
        if(dep[u]<dep[v])
        {
            T.update(dfn[u],dfn[v],w);
        }
        else
        {
            T.update(dfn[v],dfn[u],w);
        }
    }
    ll lca(ll u,ll v)
    {
        while(top[u]!=top[v])
        {
            if(dep[top[u]]>dep[top[v]])
            {
                u=fa[top[u]];
            }
            else
            {
                v=fa[top[v]];
            }
        }
        return dep[u]<dep[v]?u:v;
    }
    ll query(ll u,ll v)
    {	
        ll rt=lca(u,v);
        if(dep[u]+dep[v]-2*dep[rt]>=47)
        {
            return 1;
        }
        tmp.clear();
        tmp.push_back(T.getsum(dfn[rt]));
        while(u!=rt)
        {
            tmp.push_back(T.getsum(dfn[u]));
            u=fa[u];
        }
        while(v!=rt)
        {
            tmp.push_back(T.getsum(dfn[v]));
            v=fa[v];
        }
        sort(tmp.begin(),tmp.end());
        for(ll i=0;i+2<tmp.size();i++)
        {
            if(tmp[i]+tmp[i+1]>tmp[i+2])
            {
                return 1;
            }
        }
        return 0;
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif	
        ll q,u,v,w,pd,i;
        cin>>n>>q;
        for(i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        for(i=1;i<=n-1;i++)
        {
            cin>>u>>v;
            add(u,v);
            add(v,u);
        }
        dfs1(1,0);
        dfs2(1,1);
        for(i=1;i<=n;i++)
        {
            T.update(dfn[i],dfn[i],a[i]);
        }
        for(i=1;i<=q;i++)
        {
            cin>>pd>>u>>v;
            if(pd==1)
            {
                cin>>w;
                update(u,v,w);
            }
            else
            {
                cout<<query(u,v);
            }
        }
        return 0;
    }
    

CF1991F Triangle Formation

  • 选取的两个三角形排序后不交是容易处理的,难点在于相交的情况。

  • 不妨取连续六个一起选然后判断即可。

    点击查看代码
    int a[100010];
    vector<int>b,pos,tmp;
    int check()
    {
        sort(pos.begin(),pos.end());
        for(int i=1;i<=4;i++)
        {
            for(int j=i+1;j<=5;j++)
            {
                if(pos[0]+pos[i]>pos[j])
                {
                    tmp.clear();
                    for(int k=1;k<=5;k++)
                    {
                        if(k!=i&&k!=j)
                        {
                            tmp.push_back(pos[k]);
                        }
                    }
                    if(tmp[0]+tmp[1]>tmp[2])
                    {
                        return 1;
                    }
                }
            }
        }
        return 0;
    }
    int ask(int l,int r)
    {
        if(r-l+1>=48)
        {
            return 1;
        }
        b.clear();
        pos.clear();
        for(int i=l;i<=r;i++)
        {
            b.push_back(a[i]);
        }
        sort(b.begin(),b.end());
        for(int i=0;i+2<b.size();i++)
        {
            if(b[i]+b[i+1]>b[i+2])
            {
                pos.push_back(i);
            }
        }
        if(pos.size()>=2&&pos.back()-pos.front()>=3)
        {
            return 1;
        }
        for(int i=0;i+5<b.size();i++)
        {
            pos.clear();
            for(int j=i;j<=i+5;j++)
            {
                pos.push_back(b[j]);	
            }
            if(check()==1)
            {
                return 1;
            }
        }
        return 0;
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int n,q,l,r,i;
        scanf("%d%d",&n,&q);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=1;i<=q;i++)
        {
            scanf("%d%d",&l,&r);
            if(ask(l,r)==1)
            {
                printf("YES\n");
            }
            else
            {
                printf("NO\n");
            }
        }
        return 0;
    }
    

[ABC129F] Takahashi's Basics in Education and Learning

  • luogu P3216 [HNOI2011] 数学作业 ,矩阵快速幂加速。

    点击查看代码
    ll p;
    struct Matrix
    {
        __int128_t ma[4][4];
        Matrix()
        {
            memset(ma,0,sizeof(ma));
        }
        Matrix operator * (const Matrix another)
        {
            Matrix ans;
            for(ll i=1;i<=3;i++)
            {
                for(ll j=1;j<=3;j++)
                {
                    for(ll h=1;h<=3;h++)
                    {
                        ans.ma[i][j]=(ans.ma[i][j]+(ma[i][h]%p)*(another.ma[h][j]%p)%p)%p;
                    }
                }
            }
            return ans;
        }
    }f,Base;
    Matrix qpow(Matrix a,ll b,ll p)
    {
        Matrix ans;
        for(ll i=1;i<=3;i++)
        {
            ans.ma[i][i]=1;
        }
        while(b)
        {
            if(b&1)
            {
                ans=ans*a;
            }
            b>>=1;
            a=a*a;
        }
        return ans;
    }
    int main()
    {
    // #define Isaac
    #ifdef Isaac
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        ll a,b,n,cnt;
        cin>>n>>a>>b>>p;
        f.ma[1][1]=0;
        f.ma[1][2]=a;
        f.ma[1][3]=1;
        for(ull i=10;i<=1000000000000000000;i*=10)
        {
            if(a<=i)
            {
                cnt=min(n,(ll)ceil(1.0*(i-a)/b));
                n-=cnt;
                a+=cnt*b;
                if(cnt>=1)
                {
                    Base.ma[1][1]=i%p;
                    Base.ma[1][2]=0;
                    Base.ma[1][3]=0;
                    Base.ma[2][1]=1;
                    Base.ma[2][2]=1;
                    Base.ma[2][3]=0;
                    Base.ma[3][1]=0;
                    Base.ma[3][2]=b%p;
                    Base.ma[3][3]=1;
                    f=f*qpow(Base,cnt,p);
                }
            }
        }
        printf("%lld\n",f.ma[1][1]);
        return 0;
    }
    

12.18

闲话

  • 下午补课的时候 huge 说有学长过来给做指导,让我们也去隔壁机房听一下。到了之后 huge 先介绍了下学长的学习经历( hzoi2017 ,于 noip2018 退役,高考后去了北航而且高考分也挺高,专业是信息安全),尝试开贺出其各社交媒体账号但失败了,只贺出来了学生照片,还被学长拍照发到了群里。然后学长做了个自我介绍,给我们发了棒棒糖,中途 huge 让我们自由大胆地问想问的问题,学长都能进行解答,但因众人过于腼腆遂没什么问的。学长讲了下他的大学学习经历,提到不要给自己“大学后就可以放松了”之类的心理暗示, huge 也提到大学后只是没有人督促你必须卷了,但如果自己想上进的话还是不得不卷。然后吐槽了下北航的课程体系安排,讲到按照我们现在的实力到大学后只要不是 PKU,THU 之类的“牛棚”大学基本都能进校队且大概率会成为校队的主力队员,比其他奥赛好点的地方基本上只有实践性数据结构了,他当数据结构课程主讲人也基本在吃高中学算法竞赛的老本,而且遇到理论性数据结构时提醒我们一定要跟老师上课所讲的 PPT 对照一下(别出现考试时很快就做完了,下场后发现都不对)。还提醒我们选大学及专业时一定要集思广益,别被招生办一张嘴以自由转专业骗走了, huge 也提到在毕业后都会把拉到一个群里,群里都是毕业的往届学长帮我们指点大学、就业选择,学长还说群里的人晚上基本都跟不睡觉一样,随问随答。

做题纪要

[AGC016C] +/- Rectangle

[AGC049D] Convex Sequence

12.19

闲话

做题纪要

12.20

闲话

做题纪要

posted @   hzoi_Shadow  阅读(59)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
扩大
缩小
点击右上角即可分享
微信分享提示