BZOJ 2124: 等差子序列 [树状数组][hash]

来源:互联网 发布:牛肉汤成本算法 编辑:程序博客网 时间:2024/06/06 10:07

题面传送门

题解

只要找有没有长度为3的等差子序列

是一个排列,用一个辅助数组b[i]=0/1记录i有没有出现过

按顺序修改b,如果数为x,则查找是否有以x为等差中项的数对(l,r),并且这对数应该是一个出现了另一个没出现(b[l]==1&&b[r]==0)

可以用树状数组或线段树维护b的hash值,正着一个反着一个,判断在b中以x为中项的极长序列是否为回文串,如果不是就说明出现了长度为3的等差子序列

#include<cstdio>#include<algorithm>#include<cstring>#define N 10005#define ULL unsigned long longusing namespace std;int n;ULL pw[N],t[2][N];inline int read(){    int a=0;char f=1,c=getchar();    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}    while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}    return a*f;}inline void add(int opt,int x){    for(int i=x;i<=n;i+=i&-i)        t[opt][i]+=pw[i-x];}inline ULL ask(int opt,int x){    ULL res=0;    for(int i=x;i;i-=i&-i)        res+=t[opt][i]*pw[x-i];    return res;}inline ULL query(int opt,int l,int r){    ULL ql=ask(opt,l-1),qr=ask(opt,r);    return qr-ql*pw[r-l+1];}int main(){    pw[0]=1;for(int i=1;i<=10000;++i) pw[i]=pw[i-1]*233;    int T=read();    while(T--){        n=read();        memset(t,0,sizeof(t));        bool flag=0;        for(int i=1;i<=n;++i){            int x=read();            if(flag) continue;            int len=min(x-1,n-x);            if(len&&query(0,x-len,x-1)!=query(1,n-(x+len-1),n-x)) flag=1;            add(0,x),add(1,n-x+1);        }        if(!flag) puts("N");        else puts("Y");    }    return 0;}

wa了无数发我以为是hash的问题终于决定找份代码对拍,肉眼看了一下发现我居然有一句调试语句没有删,而且不是我自己加的调试语句…

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 康定新都桥 奥斯康定 康定木格措 康定情缘 康定机场 雅安到康定 康定到成都 康定莲花湖 康定美食 康定图片 康定温泉 康定在哪 成都至康定 康定到稻城 康定三日游 康定两日游 甘孜州康定 康定3日游 成都去康定 康定旅游团 康定2日游 康定去稻城 康定跟团游 新都桥 康定 康定 旅游 康定5日游 康定旅行社 康定二日游 康定特产 康定飞成都 康定旅行团 康定 包车 康定去成都 稻城去康定 陕西康定 云南康定 拉萨 康定 康定 景点 康定到甘孜 康定汽车站 赛康定