tg 82 solution

T1

对于每个包,时间复杂度要求O(n)O(nlogn)

Subtask 1

这个包考虑O(nlogn)的二分就可以过,下面会讲

Subtask 2

考虑充分利用"连续"这个性质

事实上我们考虑查ii1,相同就没事,否则开个新连续段

Subtask 3

cnt3,n1000,Q2000

这一部分的做法显然不能O(nlogn),考虑O(n)

注意到cnt3,我们对于每一种颜色,记录它上一个出现的位置,记为last

对于每个i,左端点定last从后往前扫,如果查询颜色数同i1那说明i颜色同左端点

否则接着扫就完了,扫完记得更新last

询问3n,最后一个last没必要扫,询问2n

Subtask 4

上面的东西询问变成3n,对上面的东西做个优化

手动二分一下,倒着按3,2,4,1的顺序,不写很详细了

然后就没有然后了,对于每个点每个分支至多查2

查询2n

这一部分没讲太细,所以放码了

点击查看代码
struct node{
    int id,val;
    bool operator<(node y){return id<y.id;}
}l[o];
int Query(int l,int r){
    if(q[l].find(r)!=q[l].end())return q[l][r];
    return q[l][r]=query(l,r);
}
void solve4(int n){
    memset(l, 0, sizeof(l));
    l[1].val = l[1].id = 1;
    l[2].val = 2; l[3].val = 3; l[4].val = 4;
    memset(c, 0, sizeof(c));
    c[1] = 1;
    ans.emplace_back(1);
    for(int i=2;i<=n;i++){
        sort(l + 1,l + 5);
        if(query(max(l[3].id, 1),i) == 3){
            if(query(max(1, l[2].id), i) == 3){
                c[i] = l[2].val;
                l[2].id = i;
            }
            else{
                c[i] = l[1].val;
                l[1].id = i;
            }
        }
        else{
            if(query(max(1, l[4].id), i) == 1){
                c[i] = l[4].val;
                l[4].id = i;
            }
            else{
                c[i] = l[3].val;
                l[3].id = i;
            }
        }
        ans.emplace_back(c[i]);
    }
    // for(int i=1;i<=n;i++)ans.push_back(c[i]);    
}
Subtask 5

出题人不会放出cnt=n的数据的

如果有,那直接[1,n]挨个装一遍

否则,找到第一个重的位置,然后直接把重掉的位置换掉

如果重复,会有[1,pos]的数量不是pos

扫第二遍重复的时候就是把1换成i,重复就是区间数量不等于posi+1

查询次数2n

Subtask 6

这个放给暴力

Subtask 7

这个时候暴力废了,二分就完事了

如果端点一定,那区间长度增大,查询结果单调不降

考虑二分找到上一个和它相同的点

如果在mid位置,查询[mid,i1]结果小于[mid,i]说明应该左移,否则右移

如果直接查询的话,询问2nlogn

考虑去掉常数,因为[mid,i1]这一段是知道的,所以直接在已有信息上暴扫就好了

花费在暴扫上的时间复杂度O(n2logn),查询nlogn

T2

把连续段缩到一起,问题可以有很简洁的表述方式。

对于长度为n的序列a,每个位置还有一个值c表示连续段长度。

每次选择i<ja[i]=a[j],操作是--c[i],++c[j]

每种颜色是独立的,只用考虑可以得到哪些c,这个可以用前缀和限制。

问题转化成了普通的子序列匹配问题。

T3

没有细想,直接看沈老师题解

问题明显是构造出连通图。

连通图至少有n1条边,所以奇数的段不能超过两个。

这个就是存在解的充要条件。

把奇数段放在头尾,构造a[1]1,a[2],a[3],a[m]+1即可,

画个图很清楚,好像这样构造出来是一条链。

T4

posted @   2K22  阅读(21)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示