"毒瘤出题组" 批斗 大会

博客围绕“毒瘤出题组”展开,主要讲述了一道关于两段序列LCS相关问题的题目出题过程。出题者受LCS启发出题,过程中不断改进,最初代码被指出问题,经过多次改动仍有错误,最后推出第三版代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“毒瘤出题组” 批斗 大会

1.批斗现场

“毒瘤者下毒瘤题,爆零得分你和我”
“你喜欢 ****** 和出毒瘤题”

2.题目简述

给出两段序列A,B求出两段序列的
(1)LCS长度
(2)LCS个数
(3)在A中尽量靠后的LCS
(4)在A中尽量靠前的LCS

3.题目背景

讲真,出原创题是真心脑袋疼…

有一天,我看了LCS,然后突发奇想…
“能不能求有多少个LCS呢”
然后我模拟了一下…
貌似有方法…
我把用lower_bound查找的那个数组用一个cnt数组分别加起来,不就是乘法原理嘛
“嗯,就这样…”
“某不知名的程姓男子,你要出题不?”

4.心路历程

“这道题貌似有点简单,不能这么水呀…”
“要想一个办法”
“要不我学一学SCOI2019 D2T3?尽量往数学方面靠?”

然后就是一顿难受的出题和造数据过程
最原来的CODE(WRONG):

#include <bits/stdc++.h>
#define inf 1e8+7
using namespace std;
const int maxn=700005;
template <typename t>void read(t &x)
{
    x=0;int f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x=x*f;
}
int n,num[maxn],b[maxn],cnt[maxn],g[maxn],fir[maxn],a[maxn],flag[10];
int size=0,ans,m;
 
void init()
{
    freopen("juruo.in","r",stdin);
    freopen("juruo.out","w",stdout);
}
 
void readdata()
{
    read(n);int x;
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        num[a[i]]=i;
    }
    for(int i=1;i<=n;i++)
    {
        read(x);
        if(num[x])b[++size]=num[x];
    }
    for(int i=1;i<=4;i++)
    {
        read(flag[i]);
    }
}
 
void work()
{
    for(int i=1;i<=size;i++)g[i]=inf;
    for(int i=1;i<=size;i++)
    {
        int k=lower_bound(g+1,g+n+1,b[i])-g;
        if(g[k]==inf)
        {
            fir[k]=b[i];
        }
        ++cnt[k];
        g[k]=b[i];
        ans=max(ans,k);
    }
    long long ans2=1;
    //////ans1
    if(flag[1])
    {
        printf("Ans(1)=");  
        printf("%d\n",ans);
    }
 
    /////ans2
    if(flag[2])
    {
        printf("Ans(2)=");
        for(int i=1;i<=ans;i++)
        {
            ans2=ans2*cnt[i];
        }
        printf("%lld\n",ans2);
    }
     
     
     
    /////ans3_max
    if(flag[3])
    {
        printf("Ans(3)=");
        for(int i=1;i<=ans;i++)
        {
            printf("%d ",a[fir[i]]);
        }
        printf("\n");
    }
     
     
    /////ans4_min
    if(flag[4])
    {
        printf("Ans(4)=");
        for(int i=1;i<=ans;i++)
        {
            printf("%d ",a[g[i]]);
        }
        printf("\n");
    }
     
}
 
int main()
{
//  init();
    readdata();
    work();
    return 0;
}

“嗯,我的题出好了”

讲一讲我最开始的想法吧。。。

“程,我貌似Hank掉了你的程序!”
“???你怎么会有我的code???”
经过一番请教过后,发现的确有问题

比如
4
1 2 3 4
1 4 2 3
1 1 1 1

然后,我发现我贪心出了问题,经过一番改动
又有了CODE(WRONG):

#include <bits/stdc++.h>
#define inf 1e8+7
using namespace std;
const int maxn=700005;
template <typename t>void read(t &x)
{
    x=0;int f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x=x*f;
}
int n,num[maxn],b[maxn],cnt[maxn],g[maxn],a[maxn],flag[10];
int size=0,ans,m,tot;
vector<int>ve[105];
int fir[105];
 
void init()
{
    freopen("juruo10.in","r",stdin);
    freopen("juruo10.out","w",stdout);
}
 
void readdata()
{
    read(n);int x;
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        num[a[i]]=i;
    }
    for(int i=1;i<=n;i++)
    {
        read(x);
        if(num[x])b[++size]=num[x];
    }
    for(int i=1;i<=4;i++)
    {
        read(flag[i]);
    }
}
 
void work()
{
    for(int i=1;i<=size;i++)g[i]=inf;
    if(n>100)
    {
        for(int i=1;i<=size;i++)
        {
            int k=lower_bound(g+1,g+n+1,b[i])-g;
            g[k]=b[i];
            ans=max(ans,k);
        }
    }
    else if(n<=100)
    {
        for(int i=1;i<=size;i++)
        {
            int k=lower_bound(g+1,g+n+1,b[i])-g;
            if(g[k]==inf)
            {
                tot++;
            }
            g[k]=b[i];
            ++cnt[k];
            ve[k].push_back(g[k]);      
            ans=max(ans,k);
        }
    }
    int ans2=1;
    //////ans1
    if(flag[1])
    {
        printf("Ans(1)=");  
        printf("%d\n",ans);
    }
 
    /////ans2
    if(flag[2])
    {
        int ans2=1;
        printf("Ans(2)=");
        for(int i=1;i<tot;i++)
        {
            int j=0,k=0,len=ve[i].size();
            while(ve[i][j]>ve[i+1][0])
            {
                cnt[i]--;
                if(j==len-1)break;
                j++;
            }
            fir[i]=j;
        }
        for(int i=1;i<=tot;i++)
        {
            ans2=ans2*cnt[i];
        }
        printf("%d\n",ans2);
    }
     
    /////ans3_max
    if(flag[3])
    {
        printf("Ans(3)=");
        for(int i=1;i<=tot;i++)
        {
            int m=ve[i].size();
            printf("%d ",a[ve[i][fir[i]]]);
        }
        printf("\n");
    }
     
    /////ans4_min
    if(flag[4])
    {
        printf("Ans(4)=");
        for(int i=1;i<=ans;i++)
        {
            printf("%d ",a[g[i]]);
        }
        printf("\n");
    }
}
 
int main()
{
    //init();
    readdata();
    work();
    return 0;
}

改动的地方:

“程,你的code有问题呀!”
“WHAT?怎么你也有我的CODE?”
比如这组数据
4
1 2 3 4
1 4 3 2
1 1 1 1

错误之处:

改动的地方:

临时花了10分钟改代码…
于是有了CODE 第三版(欢迎Hank):

#include <bits/stdc++.h>
#define inf 1e8+7
using namespace std;
const int maxn=700005;
template <typename t>void read(t &x)
{
    x=0;int f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x=x*f;
}
int n,num[maxn],b[maxn],cnt[maxn],g[maxn],a[maxn],flag[10],id[maxn];
int size=0,ans,m,tot;
vector<pair<int,int> >ve[105];
int fir[105];
 
void init()
{
    freopen("juruo.in","r",stdin);
   // freopen("juruo.out","w",stdout);
}
 
void readdata()
{
    read(n);int x;
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        num[a[i]]=i;
    }
    for(int i=1;i<=n;i++)
    {
        read(x);
        if(num[x])
		{
			b[++size]=num[x];
			id[b[size]]=i;
		}
        
    }
    for(int i=1;i<=4;i++)
    {
        read(flag[i]);
    }
}
 
void work()
{
    for(int i=1;i<=size;i++)g[i]=inf;
    if(n>100)
    {
        for(int i=1;i<=size;i++)
        {
            int k=lower_bound(g+1,g+n+1,b[i])-g;
            g[k]=b[i];
            ans=max(ans,k);
        }
    }
    else if(n<=100)
    {
        for(int i=1;i<=size;i++)
        {
            int k=lower_bound(g+1,g+n+1,b[i])-g;
            if(g[k]==inf)
            {
                tot++;
            }
            g[k]=b[i];
            ++cnt[k];
            ve[k].push_back(make_pair(id[g[k]],g[k]));      
            ans=max(ans,k);
        }
    }
    int ans2=1;
    //////ans1
    if(flag[1])
    {
        printf("Ans(1)=");  
        printf("%d\n",ans);
    }
 
    /////ans2
    if(flag[2])
    {
        int ans2=1;
        printf("Ans(2)=");
        for(int i=1;i<tot;i++)
        {
            int j=0,k=0,len=ve[i].size();
			int xx=ve[i][j].first;
            int yy=ve[i+1][0].first;
            int xxs=ve[i][j].second;
            int yys=ve[i+1][0].second;
            while(ve[i][j].second>ve[i+1][0].second)
            {
                cnt[i]--;
                if(j==len-1)break;
                j++;
            }
            for(int k=0;k<len;k++)
            {
            	if(ve[i][k].first>ve[i+1][0].first)
            	{
            		cnt[i]--;
            	    if(j==len-1)break;
               	 j++;
				}
			}
            fir[i]=j;
        }
        for(int i=1;i<=tot;i++)
        {
            ans2=ans2*cnt[i];
        }
        printf("%d\n",ans2);
    }
     
    /////ans3_max
    if(flag[3])
    {
        printf("Ans(3)=");
        for(int i=1;i<=tot;i++)
        {
            int m=ve[i].size();
            printf("%d ",a[ve[i][fir[i]].second]);
        }
        printf("\n");
    }
     
    /////ans4_min
    if(flag[4])
    {
        printf("Ans(4)=");
        for(int i=1;i<=ans;i++)
        {
            printf("%d ",a[g[i]]);
        }
        printf("\n");
    }
}
 
int main()
{
    init();
    readdata();
    work();
    return 0;
}
T23713 [愚人节题目2]数据结构大毒瘤 提交答案加入题单复制题目 提交 1.47k 通过 273 时间限制 1.00s 内存限制 125.00MB 题目编号 T23713 提供者 洛谷官方团队 难度 暂无评定 历史分数 暂无 提交记录 标签 洛谷原创 推荐题目 暂无 复制 Markdown 展开 进入 IDE 模式 题目背景 这是一道毒瘤题 这题太难了,所以窝先卖个萌0=w=0 窝从没出过这么难的题!!!! 题目描述 你好啊~这是一道数据结构毒瘤题~ 您需要维护一个数列S~ 有7种操作,形如w a b c w=0 输出S a ​ +S a+1 ​ +...+S b ​ 。c没有用 w=1 将[S a ​ ,S b ​ ]翻转。c没有用 w=2 将[S a ​ ,S b ​ ]内的数全部加上c。 w=3 将[S a ​ ,S b ​ ]内的数全部乘上c。 w=4 将[S a ​ ,S b ​ ]内的数全部开根号。c没有用 w=5 将S a ​ 加上c,将S a+1 ​ 加上2c,...,将S b ​ 加上c*(b-a+1) w=6 将[S a ​ ,S b ​ ]和[S b+1 ​ ,S c ​ ]交换。保证c-b=b-a+1。 输入格式 第一行是n和m,n表示初始序列的长度,m表示操作数量 然后n个整数,表示初始序列S 之后m行每行四个数w a b c,代表一个操作 输出格式 对于每个0操作,输出一行表示答案 输入输出样例 输入 #1复制 5 1 1 2 3 4 5 0 1 2 3 输出 #1复制 3 说明/提示 样例解释 第一次操作,询问的答案为1+2=3 数据范围 1≤n,m≤5×10 4 ,0≤w≤9,1≤a≤b≤n 保证任何时候S i ​ ∈[−10 9 ,10 9 ] 保证输入所有数∈[−10 9 ,10 9 ]
最新发布
07-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值