bzoj2124: 等差子序列线段树+hash

bzoj2124: 等差子序列线段树+hash

链接

https://www.lydsy.com/JudgeOnline/problem.php?id=2124

思路

找大于3的等差数列其实就是找等于三的等差数列
三个等差数列的话,枚举中间点。
如果有对称点(a[i]-j,a[i]+j)在两侧,那么就能构成一个等差数列
我们可以转化为权值数组中a[i]能到达的最远对称串是否是回文串。
马拉车??不不。hash是万能的。
这里hash可以用线段树维护

错误

我太菜了,代码写的特恶心

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#define ull unsigned long long
using namespace std;
const int N=2e5+7;
const int mod=233;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,pos[N],a[N];
ull my_pow[N];
namespace BIT {
    int lowbit(int x) {return x&-x;}
    ull sum[2][N];
    void add(int id) {
        for(int i=id;i<=n;i+=lowbit(i))
            sum[0][i]+=my_pow[id];
        for(int i=n-id+1;i<=n;i+=lowbit(i))
            sum[1][i]+=my_pow[n-id+1];
    }
    ull QQ0(int x,int y) {
        ull ans=0;
        if(x-1) for(int i=x-1;i>=1;i-=lowbit(i)) ans-=sum[0][i];
        for(int i=y;i>=1;i-=lowbit(i)) ans+=sum[0][i];
        return ans;
    }
    ull QQ1(int x,int y) {
        ull ans=0;
        if(x-1) for(int i=x-1;i>=1;i-=lowbit(i)) ans-=sum[1][i];
        for(int i=y;i>=1;i-=lowbit(i)) ans+=sum[1][i];
        return ans; 
    }
}
// bool dsr[N];
int main() {
    // freopen("1.in","r",stdin);
    int T=read();
    my_pow[1]=1;
    for(int i=2;i<=10000;++i) my_pow[i]=my_pow[i-1]*233;
    while(T--) {
        memset(BIT::sum,0,sizeof(BIT::sum));
        n=read();
        for(int i=1;i<=n;++i) a[i]=read();
        bool flag=false;
        for(int i=1;i<=n;++i) {
            int len=min(a[i]-1,n-a[i]);
            // for(int k=1;k<=n;++k) cout<<dsr[k]<<" <";puts("");
            // cout<<a[i]-len<<" "<<a[i]<<" vs "<<a[i]<<" "<<a[i]+len<<"  <len\n";
            int x=a[i]-len,y=a[i];
            int y_=n-a[i]+1,x_=n-(a[i]+len)+1;
            int tmp0=1,tmp1=1;
            // cout<<x<<" "<<y<<" vs "<<x_<<" "<<y_<<"\n";
            if(x>x_) tmp1+=x-x_;
            else tmp0+=x_-x;
            // cout<<tmp0<<" "<<tmp1<<"\n";
            if(BIT::QQ0(x,y)*my_pow[tmp0]!=BIT::QQ1(x_,y_)*my_pow[tmp1]) {
                puts("Y");
                // cout<<i<<" "<<a[i]<<"\n";
                flag=true;
                break;
            }
            BIT::add(a[i]);
            // dsr[a[i]]=1;
        }
        if(!flag) puts("N");
    }
    return 0;
}
全部评论

相关推荐

行云流水1971:这份实习简历的优化建议: 结构清晰化:拆分 “校园经历”“实习经历” 板块(当前内容混杂),按 “实习→校园→技能” 逻辑排版,求职意向明确为具体岗位(如 “市场 / 运营实习生”)。 经历具象化:现有描述偏流程,需补充 “动作 + 数据”,比如校园活动 “负责宣传” 可加 “运营公众号发布 5 篇推文,阅读量超 2000+,带动 300 + 人参与”;实习内容补充 “协助完成 XX 任务,效率提升 X%”。 岗位匹配度:锚定目标岗位能力,比如申请运营岗,突出 “内容编辑、活动执行” 相关动作;申请市场岗,强化 “资源对接、数据统计” 细节。 信息精简:删减冗余表述(如重复的 “负责”),用短句分点,比如 “策划校园招聘会:联系 10 + 企业,组织 200 + 学生参与,到场率达 85%”。 技能落地:将 “Office、PS” 绑定经历,比如 “用 Excel 整理活动数据,输出 3 份分析表;用 PS 设计 2 张活动海报”,避免技能单独罗列。 优化后需强化 “经历 - 能力 - 岗位需求” 的关联,让实习 / 校园经历的价值更直观。 若需要进一步优化服务,私信
实习,投递多份简历没人回...
点赞 评论 收藏
分享
01-19 15:14
已编辑
延安大学 C++
累死的一条狗:我说白了这种玩意你直接点举报就完事了在给他挂出来
找工作以来,你最看不惯_...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务